diff --git a/.clang-format b/.clang-format index 7e67aae1111..967cb046a11 100644 --- a/.clang-format +++ b/.clang-format @@ -236,6 +236,8 @@ ForEachMacros: - LOOP_UNSELECTED_POINTS - LOOP_VISIBLE_KEYS - LOOP_VISIBLE_POINTS + - LIGHT_FOREACH_BEGIN_DIRECTIONAL + - LIGHT_FOREACH_BEGIN_LOCAL - LISTBASE_CIRCULAR_BACKWARD_BEGIN - LISTBASE_CIRCULAR_FORWARD_BEGIN - LISTBASE_FOREACH diff --git a/.gitmodules b/.gitmodules index a8f3a3f80ab..9fd3a9a2c46 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,20 +1,20 @@ [submodule "release/scripts/addons"] path = release/scripts/addons url = ../blender-addons.git - branch = master + branch = main ignore = all [submodule "release/scripts/addons_contrib"] path = release/scripts/addons_contrib url = ../blender-addons-contrib.git - branch = master + branch = main ignore = all [submodule "release/datafiles/locale"] path = release/datafiles/locale url = ../blender-translations.git - branch = master + branch = main ignore = all [submodule "source/tools"] path = source/tools url = ../blender-dev-tools.git - branch = master + branch = main ignore = all diff --git a/CMakeLists.txt b/CMakeLists.txt index 1445b0a87e2..c6de0fb001d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -625,8 +625,10 @@ mark_as_advanced( # Vulkan option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF) +option(WITH_VULKAN_GUARDEDALLOC "Use guardedalloc for host allocations done inside Vulkan (development option)" OFF) mark_as_advanced( WITH_VULKAN_BACKEND + WITH_VULKAN_GUARDEDALLOC ) # Metal diff --git a/build_files/build_environment/cmake/gmp.cmake b/build_files/build_environment/cmake/gmp.cmake index ffab5ed00e5..f19d2ea3c63 100644 --- a/build_files/build_environment/cmake/gmp.cmake +++ b/build_files/build_environment/cmake/gmp.cmake @@ -22,7 +22,7 @@ elseif(UNIX AND NOT APPLE) ) endif() -# Boolean crashes with Arm assembly, see T103423. +# Boolean crashes with Arm assembly, see #103423. if(BLENDER_PLATFORM_ARM) set(GMP_OPTIONS ${GMP_OPTIONS} diff --git a/build_files/build_environment/cmake/igc.cmake b/build_files/build_environment/cmake/igc.cmake index 3b488a77b3f..f58fb44b72b 100644 --- a/build_files/build_environment/cmake/igc.cmake +++ b/build_files/build_environment/cmake/igc.cmake @@ -40,7 +40,8 @@ ExternalProject_Add(external_igc_llvm ${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0004-OpenCL-support-cl_ext_float_atomics.patch && ${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0005-OpenCL-Add-cl_khr_integer_dot_product.patch && ${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0001-Memory-leak-fix-for-Managed-Static-Mutex.patch && - ${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0002-Remove-repo-name-in-LLVM-IR.patch + ${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0002-Remove-repo-name-in-LLVM-IR.patch && + ${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0003-Add-missing-include-limit-in-benchmark.patch ) add_dependencies( external_igc_llvm @@ -55,9 +56,6 @@ ExternalProject_Add(external_igc_spirv_translator CONFIGURE_COMMAND echo . BUILD_COMMAND echo . INSTALL_COMMAND echo . - PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0001-update-SPIR-V-headers-for-SPV_INTEL_split_barrier.patch && - ${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch && - ${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0003-Support-cl_bf16_conversions.patch ) add_dependencies( external_igc_spirv_translator diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake index 4d9f892e729..832c0bf4b10 100644 --- a/build_files/build_environment/cmake/python.cmake +++ b/build_files/build_environment/cmake/python.cmake @@ -88,6 +88,19 @@ else() export LDFLAGS=${PYTHON_LDFLAGS} && export PKG_CONFIG_PATH=${LIBDIR}/ffi/lib/pkgconfig) + # NOTE: untested on APPLE so far. + if(NOT APPLE) + set(PYTHON_CONFIGURE_EXTRA_ARGS + ${PYTHON_CONFIGURE_EXTRA_ARGS} + # Used on most release Linux builds (Fedora for e.g.), + # increases build times noticeably with the benefit of a modest speedup at runtime. + --enable-optimizations + # While LTO is OK when building on the same system, it's incompatible across GCC versions, + # making it impractical for developers to build against, so keep it disabled. + # `--with-lto` + ) + endif() + ExternalProject_Add(external_python URL file://${PACKAGE_DIR}/${PYTHON_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index a4fc7dcc569..f3cc398c91c 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -668,9 +668,9 @@ set(SPIRV_HEADERS_FILE SPIR-V-Headers-${SPIRV_HEADERS_VERSION}.tar.gz) # compiler, the versions used are taken from the following location # https://github.com/intel/intel-graphics-compiler/releases -set(IGC_VERSION 1.0.12149.1) +set(IGC_VERSION 1.0.13064.7) set(IGC_URI https://github.com/intel/intel-graphics-compiler/archive/refs/tags/igc-${IGC_VERSION}.tar.gz) -set(IGC_HASH 44f67f24e3bc5130f9f062533abf8154782a9d0a992bc19b498639a8521ae836) +set(IGC_HASH a929abd4cca2b293961ec0437ee4b3b2147bd3b2c8a3c423af78c0c359b2e5ae) set(IGC_HASH_TYPE SHA256) set(IGC_FILE igc-${IGC_VERSION}.tar.gz) @@ -690,15 +690,15 @@ set(IGC_LLVM_FILE ${IGC_LLVM_VERSION}.tar.gz) # # WARNING WARNING WARNING -set(IGC_OPENCL_CLANG_VERSION 363a5262d8c7cff3fb28f3bdb5d85c8d7e91c1bb) +set(IGC_OPENCL_CLANG_VERSION ee31812ea8b89d08c2918f045d11a19bd33525c5) set(IGC_OPENCL_CLANG_URI https://github.com/intel/opencl-clang/archive/${IGC_OPENCL_CLANG_VERSION}.tar.gz) -set(IGC_OPENCL_CLANG_HASH aa8cf72bb239722ce8ce44f79413c6887ecc8ca18477dd520aa5c4809756da9a) +set(IGC_OPENCL_CLANG_HASH 1db6735bbcfaa31e8a9ba39f121d6bafa806ea8919e9f56782d6aaa67771ddda) set(IGC_OPENCL_CLANG_HASH_TYPE SHA256) set(IGC_OPENCL_CLANG_FILE opencl-clang-${IGC_OPENCL_CLANG_VERSION}.tar.gz) -set(IGC_VCINTRINSICS_VERSION v0.5.0) +set(IGC_VCINTRINSICS_VERSION v0.11.0) set(IGC_VCINTRINSICS_URI https://github.com/intel/vc-intrinsics/archive/refs/tags/${IGC_VCINTRINSICS_VERSION}.tar.gz) -set(IGC_VCINTRINSICS_HASH 70bb47c5e32173cf61514941e83ae7c7eb4485e6d2fca60cfa1f50d4f42c41f2) +set(IGC_VCINTRINSICS_HASH e5acd5626ce7fa6d41ce154c50ac805eda734ee66af94ef28e680ac2ad81bb9f) set(IGC_VCINTRINSICS_HASH_TYPE SHA256) set(IGC_VCINTRINSICS_FILE vc-intrinsics-${IGC_VCINTRINSICS_VERSION}.tar.gz) @@ -714,9 +714,9 @@ set(IGC_SPIRV_TOOLS_HASH 6e19900e948944243024aedd0a201baf3854b377b9cc7a386553bc1 set(IGC_SPIRV_TOOLS_HASH_TYPE SHA256) set(IGC_SPIRV_TOOLS_FILE SPIR-V-Tools-${IGC_SPIRV_TOOLS_VERSION}.tar.gz) -set(IGC_SPIRV_TRANSLATOR_VERSION a31ffaeef77e23d500b3ea3d35e0c42ff5648ad9) +set(IGC_SPIRV_TRANSLATOR_VERSION d739c01d65ec00dee64dedd40deed805216a7193) set(IGC_SPIRV_TRANSLATOR_URI https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz) -set(IGC_SPIRV_TRANSLATOR_HASH 9e26c96a45341b8f8af521bacea20e752623346340addd02af95d669f6e89252) +set(IGC_SPIRV_TRANSLATOR_HASH ddc0cc9ccbe59dadeaf291012d59de142b2e9f2b124dbb634644d39daddaa13e) set(IGC_SPIRV_TRANSLATOR_HASH_TYPE SHA256) set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz) @@ -724,15 +724,15 @@ set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}. ### Intel Graphics Compiler DEPS END ### ######################################## -set(GMMLIB_VERSION intel-gmmlib-22.1.8) +set(GMMLIB_VERSION intel-gmmlib-22.3.0) set(GMMLIB_URI https://github.com/intel/gmmlib/archive/refs/tags/${GMMLIB_VERSION}.tar.gz) -set(GMMLIB_HASH bf23e9a3742b4fb98c7666c9e9b29f3219e4b2fb4d831aaf4eed71f5e2d17368) +set(GMMLIB_HASH c1f33e1519edfc527127baeb0436b783430dfd256c643130169a3a71dc86aff9) set(GMMLIB_HASH_TYPE SHA256) set(GMMLIB_FILE ${GMMLIB_VERSION}.tar.gz) -set(OCLOC_VERSION 22.38.24278) +set(OCLOC_VERSION 22.49.25018.21) set(OCLOC_URI https://github.com/intel/compute-runtime/archive/refs/tags/${OCLOC_VERSION}.tar.gz) -set(OCLOC_HASH db0c542fccd651e6404b15a74d46027f1ce0eda8dc9e25a40cbb6c0faef257ee) +set(OCLOC_HASH 92362dae08b503a34e5d3820ed284198c452bcd5e7504d90eb69887b20492c06) set(OCLOC_HASH_TYPE SHA256) set(OCLOC_FILE ocloc-${OCLOC_VERSION}.tar.gz) diff --git a/build_files/build_environment/patches/igc_opencl_clang.diff b/build_files/build_environment/patches/igc_opencl_clang.diff index adc592dd8b2..6455e9d42ff 100644 --- a/build_files/build_environment/patches/igc_opencl_clang.diff +++ b/build_files/build_environment/patches/igc_opencl_clang.diff @@ -1,7 +1,7 @@ diff -Naur external_igc_opencl_clang.orig/CMakeLists.txt external_igc_opencl_clang/CMakeLists.txt --- external_igc_opencl_clang.orig/CMakeLists.txt 2022-03-16 05:51:10 -0600 +++ external_igc_opencl_clang/CMakeLists.txt 2022-05-23 10:40:09 -0600 -@@ -126,22 +126,24 @@ +@@ -147,22 +147,24 @@ ) endif() diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index dc7c101f91a..fe3bb9d4737 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -544,7 +544,7 @@ endfunction() function(setup_platform_linker_libs target ) - # jemalloc must be early in the list, to be before pthread (see T57998) + # jemalloc must be early in the list, to be before pthread (see #57998). if(WITH_MEM_JEMALLOC) target_link_libraries(${target} ${JEMALLOC_LIBRARIES}) endif() diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 0b7ae0532d8..ca0585ce9ad 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -440,7 +440,7 @@ string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++") # Make stack size more similar to Embree, required for Embree. string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000") -# Suppress ranlib "has no symbols" warnings (workaround for T48250) +# Suppress ranlib "has no symbols" warnings (workaround for #48250). set(CMAKE_C_ARCHIVE_CREATE " Scr ") set(CMAKE_CXX_ARCHIVE_CREATE " Scr ") # llvm-ranlib doesn't support this flag. Xcode's libtool does. diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 82bfa53b5a3..675429deb77 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -121,7 +121,7 @@ if(WITH_WINDOWS_BUNDLE_CRT) include(InstallRequiredSystemLibraries) # ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles - # redirects for this dll, for details see T88813. + # redirects for this dll, for details see #88813. foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}) string(FIND ${lib} "ucrtbase" pos) if(NOT pos EQUAL -1) diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index d367efca675..72909eb6fec 100755 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -170,7 +170,7 @@ def git_update_skip(args: argparse.Namespace, check_remote_exists: bool = True) return "rebase or merge in progress, complete it first" # Abort if uncommitted changes. - changes = check_output([args.git_command, 'status', '--porcelain', '--untracked-files=no']) + changes = check_output([args.git_command, 'status', '--porcelain', '--untracked-files=no', '--ignore-submodules']) if len(changes) != 0: return "you have unstaged changes" diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 745acbdc5b5..480dddb9c20 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -476,7 +476,7 @@ MODULE_GROUPING = { # -------------------------------BLENDER---------------------------------------- -# converting bytes to strings, due to T30154 +# Converting bytes to strings, due to #30154. BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8') BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp @@ -2200,7 +2200,7 @@ def write_rst_enum_items(basepath, key, key_no_prefix, enum_items): Write a single page for a static enum in RST. This helps avoiding very large lists being in-lined in many places which is an issue - especially with icons in ``bpy.types.UILayout``. See T87008. + especially with icons in ``bpy.types.UILayout``. See #87008. """ filepath = os.path.join(basepath, "%s.rst" % key_no_prefix) with open(filepath, "w", encoding="utf-8") as fh: diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index bce39bb89e5..f3d8426a23b 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -12,6 +12,7 @@ from bpy.props import ( PointerProperty, StringProperty, ) +from bpy.app.translations import pgettext_iface as iface_ from math import pi @@ -1664,30 +1665,48 @@ class CyclesPreferences(bpy.types.AddonPreferences): col.label(text="No compatible GPUs found for Cycles", icon='INFO') if device_type == 'CUDA': - col.label(text="Requires NVIDIA GPU with compute capability 3.0", icon='BLANK1') + compute_capability = "3.0" + col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability, + icon='BLANK1', translate=False) elif device_type == 'OPTIX': - col.label(text="Requires NVIDIA GPU with compute capability 5.0", icon='BLANK1') - col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1') + compute_capability = "5.0" + driver_version = "470" + col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability, + icon='BLANK1', translate=False) + col.label(text="and NVIDIA driver version %s or newer" % driver_version, + icon='BLANK1', translate=False) elif device_type == 'HIP': import sys if sys.platform[:3] == "win": + driver_version = "21.Q4" col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1') - col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1') + col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version, + icon='BLANK1', translate=False) elif sys.platform.startswith("linux"): + driver_version = "22.10" col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1') - col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1') + col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1', + translate=False) elif device_type == 'ONEAPI': import sys if sys.platform.startswith("win"): + driver_version = "101.4032" col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1') - col.label(text="and Windows driver version 101.4032 or newer", icon='BLANK1') + col.label(text=iface_("and Windows driver version %s or newer") % driver_version, + icon='BLANK1', translate=False) elif sys.platform.startswith("linux"): + driver_version = "1.3.24931" col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1') - col.label(text=" - intel-level-zero-gpu version 1.3.24931 or newer", icon='BLANK1') + col.label(text=iface_(" - intel-level-zero-gpu version %s or newer") % driver_version, + icon='BLANK1', translate=False) col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1') elif device_type == 'METAL': - col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1') - col.label(text="or AMD with macOS 12.3 or newer", icon='BLANK1') + silicon_mac_version = "12.2" + amd_mac_version = "12.3" + col.label(text=iface_("Requires Apple Silicon with macOS %s or newer") % silicon_mac_version, + icon='BLANK1', translate=False) + col.label(text=iface_("or AMD with macOS %s or newer") % amd_mac_version, icon='BLANK1', + translate=False) return for device in devices: diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 81f940529d1..a162b321853 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -20,7 +20,7 @@ class CyclesPresetPanel(PresetPanel, Panel): @staticmethod def post_cb(context): # Modify an arbitrary built-in scene property to force a depsgraph - # update, because add-on properties don't. (see T62325) + # update, because add-on properties don't. (see #62325) render = context.scene.render render.filter_size = render.filter_size diff --git a/intern/cycles/blender/display_driver.cpp b/intern/cycles/blender/display_driver.cpp index 8df0061d8ca..b000c8379b8 100644 --- a/intern/cycles/blender/display_driver.cpp +++ b/intern/cycles/blender/display_driver.cpp @@ -105,11 +105,12 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height) /* Bind shader now to enable uniform assignment. */ GPU_shader_bind(shader_program_); - GPU_shader_uniform_int(shader_program_, image_texture_location_, 0); + int slot = 0; + GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot); float size[2]; size[0] = width; size[1] = height; - GPU_shader_uniform_vector(shader_program_, fullscreen_location_, 2, 1, size); + GPU_shader_uniform_float_ex(shader_program_, fullscreen_location_, 2, 1, size); return shader_program_; } diff --git a/intern/cycles/blender/image.cpp b/intern/cycles/blender/image.cpp index ecea06fb1cd..32633f47c0b 100644 --- a/intern/cycles/blender/image.cpp +++ b/intern/cycles/blender/image.cpp @@ -20,7 +20,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image, : b_image(b_image), frame(frame), tile_number(tile_number), - /* Don't free cache for preview render to avoid race condition from T93560, to be fixed + /* Don't free cache for preview render to avoid race condition from #93560, to be fixed * properly later as we are close to release. */ free_cache(!is_preview_render && !b_image.has_data()) { @@ -72,7 +72,7 @@ bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaDat metadata.colorspace = u_colorspace_raw; } else { - /* In some cases (e.g. T94135), the colorspace setting in Blender gets updated as part of the + /* In some cases (e.g. #94135), the colorspace setting in Blender gets updated as part of the * metadata queries in this function, so update the colorspace setting here. */ PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; metadata.colorspace = get_enum_identifier(colorspace_ptr, "name"); diff --git a/intern/cycles/blender/light.cpp b/intern/cycles/blender/light.cpp index d5aba2041ad..49545047d9e 100644 --- a/intern/cycles/blender/light.cpp +++ b/intern/cycles/blender/light.cpp @@ -24,7 +24,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, Light *light = light_map.find(key); /* Check if the transform was modified, in case a linked collection is moved we do not get a - * specific depsgraph update (T88515). This also mimics the behavior for Objects. */ + * specific depsgraph update (#88515). This also mimics the behavior for Objects. */ const bool tfm_updated = (light && light->get_tfm() != tfm); /* Update if either object or light data changed. */ diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp index 7dfacec8fc9..ab0190ad235 100644 --- a/intern/cycles/blender/session.cpp +++ b/intern/cycles/blender/session.cpp @@ -404,7 +404,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) * point we know that we've got everything to render current view layer. */ /* At the moment we only free if we are not doing multi-view - * (or if we are rendering the last view). See T58142/D4239 for discussion. + * (or if we are rendering the last view). See #58142/D4239 for discussion. */ if (view_index == num_views - 1) { free_blender_memory_if_possible(); diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index 7df2a8cf30f..ee008bc6dca 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -766,7 +766,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph) (BlenderSession::headless || is_interface_locked) && /* 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 T71012. */ + * geometry we're baking, see #71012. */ !scene->bake_manager->get_baking() && /* Persistent data must main caches for performance and correctness. */ !is_persistent_data; diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index ed06740021d..5dc0919031f 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -648,7 +648,7 @@ GPUDevice::Mem *GPUDevice::generic_alloc(device_memory &mem, size_t pitch_paddin } if (mem_alloc_result) { - assert(transform_host_pointer(&device_pointer, shared_pointer)); + assert(transform_host_pointer(device_pointer, shared_pointer)); map_host_used += size; status = " in host memory"; } diff --git a/intern/cycles/device/hip/device_impl.cpp b/intern/cycles/device/hip/device_impl.cpp index b9bcd7edcab..010470c23ae 100644 --- a/intern/cycles/device/hip/device_impl.cpp +++ b/intern/cycles/device/hip/device_impl.cpp @@ -906,7 +906,7 @@ bool HIPDevice::should_use_graphics_interop() * possible, but from the empiric measurements it can be considerably slower than using naive * pixels copy. */ - /* Disable graphics interop for now, because of driver bug in 21.40. See T92972 */ + /* Disable graphics interop for now, because of driver bug in 21.40. See #92972 */ # if 0 HIPContextScope scope(this); diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index aadf5e02934..0d836e7c2d5 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -105,6 +105,7 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile } case METAL_GPU_AMD: { max_threads_per_threadgroup = 128; + use_metalrt = info.use_metalrt; break; } case METAL_GPU_APPLE: { @@ -585,7 +586,7 @@ void MetalDevice::erase_allocation(device_memory &mem) if (it != metal_mem_map.end()) { MetalMem *mmem = it->second.get(); - /* blank out reference to MetalMem* in the launch params (fixes crash T94736) */ + /* blank out reference to MetalMem* in the launch params (fixes crash #94736) */ if (mmem->pointer_index >= 0) { device_ptr *pointers = (device_ptr *)&launch_params; pointers[mmem->pointer_index] = 0; diff --git a/intern/cycles/integrator/render_scheduler.cpp b/intern/cycles/integrator/render_scheduler.cpp index 2e05dbbaf6e..3bfcf73eaf2 100644 --- a/intern/cycles/integrator/render_scheduler.cpp +++ b/intern/cycles/integrator/render_scheduler.cpp @@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c { /* Special trick for fast navigation: schedule multiple samples during fast navigation * (which will prefer to use lower resolution to keep up with refresh rate). This gives more - * usable visual feedback for artists. There are a couple of tricks though. */ + * usable visual feedback for artists. */ if (is_denoise_active_during_update()) { /* When denoising is used during navigation prefer using a higher resolution with less samples @@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c return 1; } - if (resolution_divider <= pixel_size_) { - /* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect - * the sample count at this resolution division, but instead assists in the calculation of - * the resolution divider. */ - return 1; - } - - if (resolution_divider == pixel_size_ * 2) { - /* When resolution divider is the previous step to the final resolution, schedule two samples. - * This is so that rendering on lower resolution does not exceed time that it takes to render - * first sample at the full resolution. */ - return 2; - } - - /* Always render 4 samples, even if scene is configured for less. - * The idea here is to have enough information on the screen. Resolution divider of 2 allows us - * to have 4 time extra samples, so overall worst case timing is the same as the final resolution - * at one sample. */ - return 4; + /* Schedule samples equal to the resolution divider up to a maximum of 4. + * The idea is to have enough information on the screen by increasing the sample count as the + * resolution is decreased. */ + /* NOTE: Changeing this formula will change the formula in + * "RenderScheduler::calculate_resolution_divider_for_time()"*/ + return min(max(1, resolution_divider / pixel_size_), 4); } bool RenderScheduler::work_need_adaptive_filter() const @@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider() /* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual * render time is somewhere on a boundary between two resolutions. */ - /* Never increase resolution to higher than the pixel size (which is possible if the scene is - * simple and compute device is fast). */ - start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_); + /* Don't let resolution drop below the desired one. It's better to be slow than provide an + * unreadable viewport render. */ + start_resolution_divider_ = min(resolution_divider_for_update, + default_start_resolution_divider_); VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_; } @@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached() int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time) { - /* TODO(sergey): There should a non-iterative analytical formula here. */ + const double ratio_between_times = actual_time / desired_time; - int resolution_divider = 1; + /* We can pass "ratio_between_times" to "get_num_samples_during_navigation()" to get our + * navigation samples because the equation for calculating the resolution divider is as follows: + * "actual_time / desired_time = sqr(resolution_divider) / sample_count". + * While "resolution_divider" is less than or equal to 4, "resolution_divider = sample_count" + * (This relationship is determined in "get_num_samples_during_navigation()"). With some + * substitution we end up with "actual_time / desired_time = resolution_divider" while the + * resolution divider is less than or equal to 4. Once the resolution divider increases above 4, + * the relationsip of "actual_time / desired_time = resolution_divider" is no longer true, + * however the sample count retrieved from "get_num_samples_during_navigation()" is still + * accurate if we continue using this assumption. It should be noted that the interaction between + * pixel_size, sample count, and resolution divider are automatically accounted for and that's + * why pixel_size isn't included in any of the equations. */ + const int navigation_samples = get_num_samples_during_navigation( + ceil_to_int(ratio_between_times)); - /* This algorithm iterates through resolution dividers until a divider is found that achieves - * the desired render time. A limit of default_start_resolution_divider_ is put in place as the - * maximum resolution divider to avoid an unreadable viewport due to a low resolution. - * pre_resolution_division_samples and post_resolution_division_samples are used in this - * calculation to better predict the performance impact of changing resolution divisions as - * the sample count can also change between resolution divisions. */ - while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) { - int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider); - resolution_divider = resolution_divider * 2; - int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider); - actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples; - } - - return resolution_divider; + return ceil_to_int(sqrt(navigation_samples * ratio_between_times)); } int calculate_resolution_divider_for_resolution(int width, int height, int resolution) diff --git a/intern/cycles/kernel/device/cpu/kernel_avx2.cpp b/intern/cycles/kernel/device/cpu/kernel_avx2.cpp index a1644fb0dfe..9d63be143f5 100644 --- a/intern/cycles/kernel/device/cpu/kernel_avx2.cpp +++ b/intern/cycles/kernel/device/cpu/kernel_avx2.cpp @@ -10,7 +10,7 @@ #ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 # define KERNEL_STUB #else -/* SSE optimization disabled for now on 32 bit, see bug T36316. */ +/* SSE optimization disabled for now on 32 bit, see bug #36316. */ # if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) # define __KERNEL_SSE__ # define __KERNEL_SSE2__ diff --git a/intern/cycles/kernel/device/cpu/kernel_sse2.cpp b/intern/cycles/kernel/device/cpu/kernel_sse2.cpp index 6f420274e4a..9a2e5cb7c3b 100644 --- a/intern/cycles/kernel/device/cpu/kernel_sse2.cpp +++ b/intern/cycles/kernel/device/cpu/kernel_sse2.cpp @@ -10,7 +10,7 @@ #ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 # define KERNEL_STUB #else -/* SSE optimization disabled for now on 32 bit, see bug T36316. */ +/* SSE optimization disabled for now on 32 bit, see bug #36316. */ # if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) # define __KERNEL_SSE2__ # endif diff --git a/intern/cycles/kernel/device/cpu/kernel_sse41.cpp b/intern/cycles/kernel/device/cpu/kernel_sse41.cpp index 1cfea5dc230..2e511c22647 100644 --- a/intern/cycles/kernel/device/cpu/kernel_sse41.cpp +++ b/intern/cycles/kernel/device/cpu/kernel_sse41.cpp @@ -10,7 +10,7 @@ #ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 # define KERNEL_STUB #else -/* SSE optimization disabled for now on 32 bit, see bug T36316. */ +/* SSE optimization disabled for now on 32 bit, see bug #36316. */ # if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) # define __KERNEL_SSE2__ # define __KERNEL_SSE3__ diff --git a/intern/cycles/kernel/device/gpu/kernel.h b/intern/cycles/kernel/device/gpu/kernel.h index 821fc1eaf15..0c2fd76fcbd 100644 --- a/intern/cycles/kernel/device/gpu/kernel.h +++ b/intern/cycles/kernel/device/gpu/kernel.h @@ -645,7 +645,7 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb const int y, const half4 half_pixel) { - /* Work around HIP issue with half float display, see T92972. */ + /* Work around HIP issue with half float display, see #92972. */ #ifdef __KERNEL_HIP__ ccl_global half *out = ((ccl_global half *)rgba) + (rgba_offset + y * rgba_stride + x) * 4; out[0] = half_pixel.x; diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index 4c5013b5a9f..c008dac7afb 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -13,6 +13,7 @@ #include "scene/light.h" #include "scene/mesh.h" #include "scene/object.h" +#include "scene/osl.h" #include "scene/pointcloud.h" #include "scene/scene.h" #include "scene/shader.h" @@ -25,7 +26,6 @@ #ifdef WITH_OSL # include "kernel/osl/globals.h" -# include "kernel/osl/services.h" #endif #include "util/foreach.h" @@ -1717,20 +1717,7 @@ void GeometryManager::device_update_displacement_images(Device *device, /* If any OSL node is used for displacement, it may reference a texture. But it's * unknown which ones, so have to load them all. */ if (has_osl_node) { - set services_shared; - device->foreach_device([&services_shared](Device *sub_device) { - OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory(); - services_shared.insert(og->services); - }); - - for (OSLRenderServices *services : services_shared) { - for (auto it = services->textures.begin(); it != services->textures.end(); ++it) { - if (it->second->handle.get_manager() == image_manager) { - const int slot = it->second->handle.svm_slot(); - bump_images.insert(slot); - } - } - } + OSLShaderManager::osl_image_slots(device, image_manager, bump_images); } #endif diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 53e993b8135..9b65b780fe4 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -394,7 +394,7 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output /* Compile. * - * Mutex protected because the OSL compiler does not appear to be thread safe, see T92503. */ + * Mutex protected because the OSL compiler does not appear to be thread safe, see #92503. */ static thread_mutex osl_compiler_mutex; thread_scoped_lock lock(osl_compiler_mutex); @@ -665,6 +665,27 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph, return node; } +/* Static function, so only this file needs to be compile with RTTT. */ +void OSLShaderManager::osl_image_slots(Device *device, + ImageManager *image_manager, + set &image_slots) +{ + set services_shared; + device->foreach_device([&services_shared](Device *sub_device) { + OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory(); + services_shared.insert(og->services); + }); + + for (OSLRenderServices *services : services_shared) { + for (auto it = services->textures.begin(); it != services->textures.end(); ++it) { + if (it->second->handle.get_manager() == image_manager) { + const int slot = it->second->handle.svm_slot(); + image_slots.insert(slot); + } + } + } +} + /* Graph Compiler */ OSLCompiler::OSLCompiler(OSLShaderManager *manager, OSL::ShadingSystem *ss, Scene *scene) diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h index c0e82a9dc8d..cfe48823143 100644 --- a/intern/cycles/scene/osl.h +++ b/intern/cycles/scene/osl.h @@ -92,6 +92,9 @@ class OSLShaderManager : public ShaderManager { const std::string &bytecode_hash = "", const std::string &bytecode = ""); + /* Get image slots used by OSL services on device. */ + static void osl_image_slots(Device *device, ImageManager *image_manager, set &image_slots); + private: void texture_system_init(); void texture_system_free(); diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index f0faa91b4be..dfd86f82bb6 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -573,7 +573,7 @@ void ShaderManager::device_update_common(Device * /*device*/, kfilm->is_rec709 = is_rec709; } -void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene) +void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene * /*scene*/) { dscene->shaders.free(); } diff --git a/intern/cycles/session/tile.cpp b/intern/cycles/session/tile.cpp index ab858e6f192..371ca4728d4 100644 --- a/intern/cycles/session/tile.cpp +++ b/intern/cycles/session/tile.cpp @@ -520,7 +520,7 @@ bool TileManager::write_tile(const RenderBuffers &tile_buffers) /* If there is an overscan used for the tile copy pixels into single continuous block of memory * without any "gaps". * This is a workaround for bug in OIIO (https://github.com/OpenImageIO/oiio/pull/3176). - * Our task reference: T93008. */ + * Our task reference: #93008. */ if (tile_params.window_x || tile_params.window_y || tile_params.window_width != tile_params.width || tile_params.window_height != tile_params.height) { diff --git a/intern/cycles/util/math_fast.h b/intern/cycles/util/math_fast.h index c7d44739af9..4ebd50fdee3 100644 --- a/intern/cycles/util/math_fast.h +++ b/intern/cycles/util/math_fast.h @@ -421,7 +421,7 @@ ccl_device_inline float fast_expf(float x) #if !defined(__KERNEL_GPU__) && !defined(_MSC_VER) /* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see - * T78047 and T78869 for details. Just disable for now, it only makes + * #78047 and #78869 for details. Just disable for now, it only makes * a small difference in denoising performance. */ ccl_device float4 fast_exp2f4(float4 x) { diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 1aa0cb9def4..4defd68b90f 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -516,7 +516,7 @@ GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles() /* OpenGL on Metal * - * Use Metal layer to avoid Viewport lagging on macOS, see T60043. */ + * Use Metal layer to avoid Viewport lagging on macOS, see #60043. */ static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm; static const OSType METAL_CORE_VIDEO_PIXEL_FORMAT = kCVPixelFormatType_32BGRA; diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index d9f2df21ee0..71ec9d1c009 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -141,7 +141,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() /* -------------------------------------------------------------------- */ #else /* Important to initialize only GLXEW (_not_ GLEW), - * since this breaks w/ Mesa's `swrast`, see: T46431. */ + * since this breaks w/ Mesa's `swrast`, see: #46431. */ glxewInit(); #endif /* USE_GLXEW_INIT_WORKAROUND */ diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index ffd9c57803c..d0309b4bba3 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -302,7 +302,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id) switch (product_id) { case 0xC62E: /* Plugged in. */ case 0xC62F: /* Wireless. */ - case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see T82412. */ + case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see #82412. */ { device_type_ = NDOF_SpaceMouseWireless; hid_map_button_num_ = 2; @@ -341,7 +341,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id) hid_map_button_mask_ = int(~(UINT_MAX << hid_map_button_num_)); } - CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, (uint)hid_map_button_mask_); + CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, uint(hid_map_button_mask_)); return device_type_ != NDOF_UnknownDevice; } @@ -445,14 +445,14 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim 2, "button=%d, press=%d (out of range %d, ignoring!)", button_number, - (int)press, + int(press), hid_map_button_num_); return; } const NDOF_ButtonT button = hid_map_[button_number]; if (button == NDOF_BUTTON_NONE) { CLOG_INFO( - LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, (int)press); + LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, int(press)); return; } @@ -460,7 +460,7 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim 2, "button=%d, press=%d, name=%s", button_number, - (int)press, + int(press), ndof_button_names[button]); GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow(); diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index 9174664adc4..e02b3817687 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -602,7 +602,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) /* NOTE: the `sdl_sub_evt.keysym.sym` is truncated, * for unicode support ghost has to be modified. */ - /* TODO(@campbellbarton): support full unicode, SDL supports this but it needs to be + /* TODO(@ideasman42): support full unicode, SDL supports this but it needs to be * explicitly enabled via #SDL_StartTextInput which GHOST would have to wrap. */ char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'}; if (type == GHOST_kEventKeyDown) { diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index d3f32cf4450..6ef593e277c 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -141,7 +141,7 @@ constexpr size_t events_pending_default_size = 4096 / sizeof(void *); * \{ */ /** - * GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793. + * GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: #98793. * Even though this has been fixed, at time of writing it's not yet in a release. * Workaround the problem by implementing confine with a software cursor. * While this isn't ideal, it's not adding a lot of overhead as software @@ -176,7 +176,7 @@ static bool use_gnome_confine_hack = false; /** * KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed - * (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: T102048. + * (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: #102048. * See: https://bugs.kde.org/show_bug.cgi?id=461001 */ #define USE_KDE_TABLET_HIDDEN_CURSOR_HACK @@ -197,8 +197,8 @@ static bool use_gnome_confine_hack = false; * \{ */ /** - * Fix short-cut part of keyboard reading code not properly handling some keys, see: T102194. - * \note This is similar to X11 workaround by the same name, see: T47228. + * Fix short-cut part of keyboard reading code not properly handling some keys, see: #102194. + * \note This is similar to X11 workaround by the same name, see: #47228. */ #define USE_NON_LATIN_KB_WORKAROUND @@ -241,7 +241,7 @@ enum { BTN_STYLUS = 0x14b, /** Use as right-mouse. */ BTN_STYLUS2 = 0x14c, - /** NOTE(@campbellbarton): Map to an additional button (not sure which hardware uses this). */ + /** NOTE(@ideasman42): Map to an additional button (not sure which hardware uses this). */ BTN_STYLUS3 = 0x149, }; @@ -916,7 +916,7 @@ struct GWL_Display { * The main purpose of having an active seat is an alternative from always using the first * seat which prevents events from any other seat. * - * NOTE(@campbellbarton): This could be extended and developed further extended to support + * NOTE(@ideasman42): This could be extended and developed further extended to support * an active seat per window (for e.g.), basic support is sufficient for now as currently isn't * a widely used feature. */ @@ -957,7 +957,7 @@ struct GWL_Display { * Needed because #GHOST_System::dispatchEvents fires timers * outside of WAYLAND (without locking the `timer_mutex`). */ - GHOST_TimerManager *ghost_timer_manager; + GHOST_TimerManager *ghost_timer_manager = nullptr; #endif /* USE_EVENT_BACKGROUND_THREAD */ }; @@ -1014,8 +1014,10 @@ static void gwl_display_destroy(GWL_Display *display) } /* Important to remove after the seats which may have key repeat timers active. */ - delete display->ghost_timer_manager; - display->ghost_timer_manager = nullptr; + if (display->ghost_timer_manager) { + delete display->ghost_timer_manager; + display->ghost_timer_manager = nullptr; + } #endif /* USE_EVENT_BACKGROUND_THREAD */ @@ -1237,7 +1239,7 @@ static void gwl_registry_entry_remove_all(GWL_Display *display) { const bool on_exit = true; - /* NOTE(@campbellbarton): Free by slot instead of simply looping over + /* NOTE(@ideasman42): Free by slot instead of simply looping over * `display->registry_entry` so the order of freeing is always predictable. * Otherwise global objects would be feed in the order they are registered. * While this works in my tests, it could cause difficult to reproduce bugs @@ -1267,7 +1269,7 @@ static void gwl_registry_entry_remove_all(GWL_Display *display) * so there is no reason to update all other outputs that an output was removed (for e.g.). * Pass as -1 to update all slots. * - * NOTE(@campbellbarton): Updating all other items on a single change is typically worth avoiding. + * NOTE(@ideasman42): Updating all other items on a single change is typically worth avoiding. * In practice this isn't a problem as so there are so few elements in `display->registry_entry`, * so few use update functions and adding/removal at runtime is rarely called (plugging/unplugging) * hardware for e.g. So while it's possible to store dependency links to avoid unnecessary @@ -1316,7 +1318,7 @@ static void ghost_wl_display_report_error(struct wl_display *display) fprintf(stderr, "The Wayland connection experienced a fatal error: %s\n", strerror(ecode)); } - /* NOTE(@campbellbarton): The application is running, + /* NOTE(@ideasman42): The application is running, * however an error closes all windows and most importantly: * shuts down the GPU context (loosing all GPU state - shaders, bind codes etc), * so recovering from this effectively involves restarting. @@ -1326,7 +1328,7 @@ static void ghost_wl_display_report_error(struct wl_display *display) * So in practice re-connecting to the display server isn't an option. * * Exit since leaving the process open will simply flood the output and do nothing. - * Although as the process is in a valid state, auto-save for e.g. is possible, see: T100855. */ + * Although as the process is in a valid state, auto-save for e.g. is possible, see: #100855. */ ::exit(-1); } @@ -1440,7 +1442,7 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym) /* Additional keys for non US layouts. */ - /* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: T102287. */ + /* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: #102287. */ GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod); default: @@ -2968,7 +2970,7 @@ static void gesture_pinch_handle_begin(void *data, if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) { win = ghost_wl_surface_user_data(wl_surface_focus); } - /* NOTE(@campbellbarton): Blender's use of track-pad coordinates is inconsistent and needs work. + /* NOTE(@ideasman42): Blender's use of track-pad coordinates is inconsistent and needs work. * This isn't specific to WAYLAND, in practice they tend to work well enough in most cases. * Some operators scale by the UI scale, some don't. * Even this window scale is not correct because it doesn't account for: @@ -2982,7 +2984,7 @@ static void gesture_pinch_handle_begin(void *data, */ const wl_fixed_t win_scale = win ? win->scale() : 1; - /* NOTE(@campbellbarton): Scale factors match Blender's operators & default preferences. + /* NOTE(@ideasman42): Scale factors match Blender's operators & default preferences. * For these values to work correctly, operator logic will need to be changed not to scale input * by the region size (as with 3D view zoom) or preference for 3D view orbit sensitivity. * @@ -3145,7 +3147,7 @@ static const struct zwp_pointer_gesture_swipe_v1_listener gesture_swipe_listener /* -------------------------------------------------------------------- */ /** \name Listener (Touch Seat), #wl_touch_listener * - * NOTE(@campbellbarton): It's not clear if this interface is used by popular compositors. + * NOTE(@ideasman42): It's not clear if this interface is used by popular compositors. * It looks like GNOME/KDE only support `zwp_pointer_gestures_v1_interface`. * If this isn't used anywhere, it could be removed. * \{ */ @@ -3806,9 +3808,9 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers( /* Use an empty keyboard state to access key symbol without modifiers. */ xkb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state_empty, key); - /* NOTE(@campbellbarton): Only perform the number-locked lookup as a fallback + /* NOTE(@ideasman42): Only perform the number-locked lookup as a fallback * when a number-pad key has been pressed. This is important as some key-maps use number lock - * for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: T96170. + * for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: #96170. * Alternative solutions could be to inspect the layout however this could get involved * and turning on the number-lock is only needed for a limited set of keys. */ @@ -3936,7 +3938,7 @@ static void keyboard_handle_key(void *data, else { /* Key-up from keys that were not repeating cause the repeat timer to pause. * - * NOTE(@campbellbarton): This behavior isn't universal, some text input systems will + * NOTE(@ideasman42): This behavior isn't universal, some text input systems will * stop the repeat entirely. Choose to pause repeat instead as this is what GTK/WIN32 do, * and it fits better for keyboard input that isn't related to text entry. */ timer_action = RESET; @@ -4465,7 +4467,7 @@ static void xdg_output_handle_logical_size(void *data, #ifdef USE_GNOME_CONFINE_HACK /* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue - * as T98793 has been fixed up-stream too, but not in a release at time of writing. */ + * as #98793 has been fixed up-stream too, but not in a release at time of writing. */ use_gnome_confine_hack = true; #endif @@ -7035,7 +7037,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod UNPACK2(xy_next)); wl_surface_commit(wl_surface); - /* NOTE(@campbellbarton): The new cursor position is a hint, + /* NOTE(@ideasman42): The new cursor position is a hint, * it's possible the hint is ignored. It doesn't seem like there is a good way to * know if the hint will be used or not, at least not immediately. */ xy_motion[0] = xy_next[0]; @@ -7078,7 +7080,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod if (mode != GHOST_kGrabDisable) { if (grab_state_next.use_lock) { if (!grab_state_prev.use_lock) { - /* TODO(@campbellbarton): As WAYLAND does not support warping the pointer it may not be + /* TODO(@ideasman42): As WAYLAND does not support warping the pointer it may not be * possible to support #GHOST_kGrabWrap by pragmatically settings it's coordinates. * An alternative could be to draw the cursor in software (and hide the real cursor), * or just accept a locked cursor on WAYLAND. */ diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index 153931a0a39..61c7f3a045c 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -208,7 +208,7 @@ class GHOST_SystemWayland : public GHOST_System { * Clear all references to this output. * * \note The compositor should have already called the `wl_surface_listener.leave` callback, - * however some compositors may not (see T103586). + * however some compositors may not (see #103586). * So remove references to the output before it's destroyed to avoid crashing. * * \return true when any references were removed. diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 75a4cc8389a..9fc69dabe00 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -424,10 +424,9 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent) processTrackpad(); - /* PeekMessage above is allowed to dispatch messages to the wndproc without us + /* `PeekMessage` above is allowed to dispatch messages to the `wndproc` without us * noticing, so we need to check the event manager here to see if there are - * events waiting in the queue. - */ + * events waiting in the queue. */ hasEventHandled |= this->m_eventManager->getNumEvents() > 0; } while (waitForEvent && !hasEventHandled); @@ -566,8 +565,8 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_key_down) /** * \note this function can be extended to include other exotic cases as they arise. * - * This function was added in response to bug T25715. - * This is going to be a long list T42426. + * This function was added in response to bug #25715. + * This is going to be a long list #42426. */ GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const { @@ -1080,11 +1079,11 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind if (window->getCursorGrabMode() == GHOST_kGrabHide) { window->getClientBounds(bounds); - /* WARNING(@campbellbarton): The current warping logic fails to warp on every event, + /* WARNING(@ideasman42): The current warping logic fails to warp on every event, * so the box needs to small enough not to let the cursor escape the window but large * enough that the cursor isn't being warped every time. * If this was not the case it would be less trouble to simply warp the cursor to the - * center of the screen on every motion, see: D16558 (alternative fix for T102346). */ + * center of the screen on every motion, see: D16558 (alternative fix for #102346). */ const int32_t subregion_div = 4; /* One quarter of the region. */ const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()}; const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2}; @@ -1179,7 +1178,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA GHOST_TKey key = system->hardKey(raw, &key_down); GHOST_EventKey *event; - /* NOTE(@campbellbarton): key repeat in WIN32 also applies to modifier-keys. + /* NOTE(@ideasman42): key repeat in WIN32 also applies to modifier-keys. * Check for this case and filter out modifier-repeat. * Typically keyboard events are *not* filtered as part of GHOST's event handling. * As other GHOST back-ends don't have the behavior, it's simplest not to send them through. @@ -1210,7 +1209,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80; const bool alt_pressed = has_state && state[VK_MENU] & 0x80; - /* We can be here with !key_down if processing dead keys (diacritics). See T103119. */ + /* We can be here with !key_down if processing dead keys (diacritics). See #103119. */ /* No text with control key pressed (Alt can be used to insert special characters though!). */ if (ctrl_pressed && !alt_pressed) { diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index de3284381a4..2de81ce46d5 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -46,7 +46,7 @@ #ifdef WITH_X11_XFIXES # include -/* Workaround for XWayland grab glitch: T53004. */ +/* Workaround for XWayland grab glitch: #53004. */ # define WITH_XWAYLAND_HACK #endif @@ -71,11 +71,11 @@ # define USE_XINPUT_HOTPLUG #endif -/* see T34039 Fix Alt key glitch on Unity desktop */ +/* see #34039 Fix Alt key glitch on Unity desktop */ #define USE_UNITY_WORKAROUND /* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map - * instead of active one. See T47228 and D1746 */ + * instead of active one. See #47228 and D1746 */ #define USE_NON_LATIN_KB_WORKAROUND static uchar bit_is_on(const uchar *ptr, int bit) @@ -278,7 +278,7 @@ uint8_t GHOST_SystemX11::getNumDisplays() const void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { if (m_display) { - /* NOTE(@campbellbarton): for this to work as documented, + /* NOTE(@ideasman42): for this to work as documented, * we would need to use Xinerama check r54370 for code that did this, * we've since removed since its not worth the extra dependency. */ getAllDisplayDimensions(width, height); @@ -927,8 +927,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe) if (window->getCursorGrabMode() == GHOST_kGrabHide) { window->getClientBounds(bounds); - /* TODO(@campbellbarton): warp the cursor to `window->getCursorGrabInitPos`, - * on every motion event, see: D16557 (alternative fix for T102346). */ + /* TODO(@ideasman42): warp the cursor to `window->getCursorGrabInitPos`, + * on every motion event, see: D16557 (alternative fix for #102346). */ const int32_t subregion_div = 4; /* One quarter of the region. */ const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()}; const int32_t center[2] = { @@ -964,7 +964,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe) if (x_new != xme.x_root || y_new != xme.y_root) { /* Use time of last event to avoid wrapping several times on the 'same' actual wrap. * Note that we need to deal with X and Y separately as those might wrap at the same time - * but still in two different events (corner case, see T74918). + * but still in two different events (corner case, see #74918). * We also have to add a few extra milliseconds of 'padding', as sometimes we get two * close events that will generate extra wrap on the same axis within those few * milliseconds. */ @@ -1028,7 +1028,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe) /* XXX: Code below is kinda awfully convoluted... Issues are: * - In keyboards like Latin ones, numbers need a 'Shift' to be accessed but key_sym * is unmodified (or anyone swapping the keys with `xmodmap`). - * - #XLookupKeysym seems to always use first defined key-map (see T47228), which generates + * - #XLookupKeysym seems to always use first defined key-map (see #47228), which generates * key-codes unusable by ghost_key_from_keysym for non-Latin-compatible key-maps. * * To address this, we: @@ -1715,7 +1715,7 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y) #if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP) if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) { - /* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */ + /* Needed to account for XInput "Coordinate Transformation Matrix", see #48901 */ int device_id; if (XIGetClientPointer(m_display, None, &device_id) != False) { XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely); diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index 1f071da6da7..4eff2850afd 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -20,8 +20,8 @@ /* Disable XINPUT warp, currently not implemented by Xorg for multi-head display. * (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4) - * If this is supported we can add back XINPUT for warping (fixing T48901). - * For now disable (see T50383). */ + * If this is supported we can add back XINPUT for warping (fixing #48901). + * For now disable (see #50383). */ // # define USE_X11_XINPUT_WARP #endif diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index f486fc319c8..066ff4aa03a 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -669,7 +669,7 @@ static void xdg_surface_handle_configure(void *data, GHOST_SystemWayland *system = win->ghost_system; const bool is_main_thread = system->main_thread_id == std::this_thread::get_id(); if (!is_main_thread) { - /* NOTE(@campbellbarton): this only gets one redraw, + /* NOTE(@ideasman42): this only gets one redraw, * I could not find a case where this causes problems. */ gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE); } @@ -774,7 +774,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, window_->ghost_window = this; window_->ghost_system = system; - /* NOTE(@campbellbarton): The scale set here to avoid flickering on startup. + /* NOTE(@ideasman42): The scale set here to avoid flickering on startup. * When all monitors use the same scale (which is quite common) there aren't any problems. * * When monitors have different scales there may still be a visible window resize on startup. @@ -812,12 +812,12 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, * when the `window_->scale` changed. */ const int32_t size_min[2] = {320, 240}; - /* This value is expected to match the base name of the `.desktop` file. see T101805. + /* This value is expected to match the base name of the `.desktop` file. see #101805. * * NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention. * For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is * simply called `blender.desktop`, so the it's important to follow that name. - * Other distributions such as SNAP & FLATPAK may need to change this value T101779. + * Other distributions such as SNAP & FLATPAK may need to change this value #101779. * Currently there isn't a way to configure this, we may want to support that. */ const char *xdg_app_id = ( #ifdef WITH_GHOST_WAYLAND_APP_ID @@ -1078,9 +1078,9 @@ GHOST_WindowWayland::~GHOST_WindowWayland() wl_surface_destroy(window_->wl_surface); - /* NOTE(@campbellbarton): Flushing will often run the appropriate handlers event + /* NOTE(@ideasman42): Flushing will often run the appropriate handlers event * (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces. - * This is not fool-proof though, hence the call to #window_surface_unref, see: T99078. */ + * This is not fool-proof though, hence the call to #window_surface_unref, see: #99078. */ wl_display_flush(system_->wl_display()); delete window_; diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index c5554f70200..04f247eef8d 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -15,7 +15,7 @@ #include /* For #wl_fixed_t */ /** - * Define to workaround for a bug/limitation in WAYLAND, see: T100855 & upstream report: + * Define to workaround for a bug/limitation in WAYLAND, see: #100855 & upstream report: * https://gitlab.freedesktop.org/wayland/wayland/-/issues/159 * * Consume events from WAYLAND in a thread, this is needed because overflowing the event queue diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 5086920be43..3e82f55c583 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -154,7 +154,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, } if (parentwindow) { - /* Release any parent capture to allow immediate interaction (T90110). */ + /* Release any parent capture to allow immediate interaction (#90110). */ ::ReleaseCapture(); parentwindow->lostMouseCapture(); } diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 00b0230888e..393944eac97 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -418,7 +418,7 @@ void GHOST_WindowX11::refreshXInputDevices() for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) { /* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event, - * otherwise we do not get any tablet motion event once pen is pressed... See T43367. + * otherwise we do not get any tablet motion event once pen is pressed... See #43367. */ XEventClass ev; @@ -1467,7 +1467,7 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode) } } - /* Perform this last so to workaround XWayland bug, see: T53004. */ + /* Perform this last so to workaround XWayland bug, see: #53004. */ if (m_cursorGrab == GHOST_kGrabHide) { setWindowCursorVisibility(true); } diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp index 80e8d89799a..dc69a374074 100644 --- a/intern/locale/boost_locale_wrapper.cpp +++ b/intern/locale/boost_locale_wrapper.cpp @@ -108,7 +108,7 @@ void bl_locale_set(const char *locale) } /* Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions * like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are - * not caught by their ancestor `std::exception`. See T88877#1177108 */ + * not caught by their ancestor `std::exception`. See #88877#1177108 */ catch (std::runtime_error const &e) { std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n"; } diff --git a/intern/locale/osx_user_locale.mm b/intern/locale/osx_user_locale.mm index 92c9eb21605..f38717f24d3 100644 --- a/intern/locale/osx_user_locale.mm +++ b/intern/locale/osx_user_locale.mm @@ -23,7 +23,7 @@ const char *osx_user_locale() [myNSLocale autorelease]; // This produces gettext-invalid locale in recent macOS versions (11.4), - // like `ko-Kore_KR` instead of `ko_KR`. See T88877. + // like `ko-Kore_KR` instead of `ko_KR`. See #88877. // NSString *nsIdentifier = [myNSLocale localeIdentifier]; const NSString *nsIdentifier = [myNSLocale languageCode]; diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 6a72cd2aacb..28c66021d23 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -193,7 +193,7 @@ static bool createGPUShader(OCIO_GPUShader &shader, info.fragment_source("gpu_shader_display_transform_frag.glsl"); info.fragment_source_generated = source; - /* T96502: Work around for incorrect OCIO GLSL code generation when using + /* #96502: Work around for incorrect OCIO GLSL code generation when using * GradingPrimaryTransform. Should be reevaluated when changing to a next version of OCIO. * (currently v2.1.1). */ info.define("inf 1e32"); diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index 24e093833c4..d75a0974f74 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -145,7 +145,7 @@ const UserDef U_default = { .ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE | /* Software from the driver authors follows this convention - * so invert this by default, see: T67579. */ + * so invert this by default, see: #67579. */ NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS | NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS | NDOF_ZOOM_INVERT | NDOF_CAMERA_PAN_ZOOM), diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index 04ad04d4812..7d0cf9b031c 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -370,6 +370,7 @@ const bTheme U_theme_default = { .clipping_border_3d = RGBA(0x3f3f3fff), .bundle_solid = RGBA(0xc8c8c8ff), .camera_path = RGBA(0x000000ff), + .camera_passepartout = RGBA(0x000000), .gp_vertex_size = 3, .gp_vertex = RGBA(0x000000ff), .gp_vertex_select = RGBA(0xff8500ff), diff --git a/release/lts/README.md b/release/lts/README.md index 8f7b6f0b87a..c95aecabe18 100644 --- a/release/lts/README.md +++ b/release/lts/README.md @@ -1,41 +1,18 @@ -This folder contains several scripts to smoothen the Blender LTS releases. +This folder contains a script to generate release notes and download URLs +for Blender LTS releases. -create_download_urls.py -======================= +Ensure required Python modules are installed before running: -This python script is used to generate the download urls which we can -copy-paste directly into the CMS of www.blender.org. + pip3 install -r ./requirements.txt -Usage: create_download_urls.py --version 2.83.7 +Then run for example: -Arguments: - --version VERSION Version string in the form of {major}.{minor}.{build} - (eg 2.83.7) + ./create_release_notes.py --version 3.3.2 --format=html -The resulting html will be printed to the console. +Available arguments: -create_release_notes.py -======================= - -This python script is used to generate the release notes which we can -copy-paste directly into the CMS of www.blender.org and stores. - -Usage: ./create_release_notes.py --task=T77348 --version=2.83.7 - -Arguments: - --version VERSION Version string in the form of {major}.{minor}.{build} - (e.g. 2.83.7) - --task TASK Phabricator ticket that is contains the release notes - information (e.g. T77348) - --format FORMAT Format the result in `text`, `steam`, `wiki` or `html` - -Requirements -============ - -* Python 3.8 or later -* Python phabricator client version 0.7.0 - https://pypi.org/project/phabricator/ - -For convenience the python modules can be installed using pip - - pip3 install -r ./requirements.txt \ No newline at end of file + --version VERSION Version string in the form of {major}.{minor}.{build} + (e.g. 3.3.2) + --issue ISSUE Gitea issue that is contains the release notes + information (e.g. #77348) + --format FORMAT Format the result in `text`, `steam`, `wiki` or `html` diff --git a/release/lts/create_release_notes.py b/release/lts/create_release_notes.py index a51721057bb..cfab24c94ae 100755 --- a/release/lts/create_release_notes.py +++ b/release/lts/create_release_notes.py @@ -1,169 +1,46 @@ +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later -#!/usr/bin/env python3 - import argparse -import phabricator +import lts_issue +import lts_download -DESCRIPTION = ("This python script is used to generate the release notes " - "which we can copy-paste directly into the CMS of " +DESCRIPTION = ("This python script is used to generate the release notes and " + "download URLs which we can copy-paste directly into the CMS of " "www.blender.org and stores.") -USAGE = "./create_release_notes.py --task=T77348 --version=2.83.7" +# Parse arguments +parser = argparse.ArgumentParser(description=DESCRIPTION) +parser.add_argument( + "--version", + required=True, + help="Version string in the form of {major}.{minor}.{patch} (e.g. 3.3.2)") +parser.add_argument( + "--issue", + help="Task that is contains the release notes information (e.g. #77348)") +parser.add_argument( + "--format", + help="Format the result in `text`, `steam`, `wiki` or `html`", + default="text") +args = parser.parse_args() -class ReleaseLogLine: - """ - Class containing the information of a single line of the release log +# Determine issue number +version = args.version +issue = args.issue +if not issue: + if version.startswith("2.83."): + issue = "#77348" + elif version.startswith("2.93."): + issue = "#88449" + elif version.startswith("3.3."): + issue = "#100749" + else: + raise ValueError("Specify --issue or update script to include issue number for this version") - Instance attributes: +# Print +if args.format == "html": + lts_download.print_urls(version=version) + print("") - * line: (str) the original line used to create this log line - * task_id: (int or None) the extracted task id associated with this log - line. Can be None if the log line isn't associated with a task. - * commit_id: (str or None) the extracted commit id associated with this log - line. Only filled when no `task_id` could be found. - * ref: (str) `task_id` or `commit_id` of this line, including `T` for tasks - or `D` for diffs. - * title: (str) title of this log line. When constructed this attribute is - an empty string. The called needs to retrieve the title from the - backend. - * url: (str) url of the ticket task or commit. - """ - - def __init__(self, line: str): - self.line = line - items = line.split("|") - self.task_id = None - self.commit_id = None - try: - task_id = int(items[1].strip()[1:]) - self.task_id = task_id - self.ref = f"T{self.task_id}" - except ValueError: - # no task - commit_string = items[3].strip() - commits = commit_string.split(",") - commit_id = commits[0] - commit_id = commit_id.replace("{", "").replace("}", "") - if not commit_id.startswith("rB"): - commit_id = f"rB{commit_id}" - self.commit_id = commit_id - - self.ref = f"{self.commit_id}" - - self.title = "" - self.url = f"https://developer.blender.org/{self.ref}" - - def __format_as_html(self) -> str: - return f"
  • {self.title} [{self.ref}]
  • " - - def __format_as_text(self) -> str: - return f"* {self.title} [{self.ref}]" - - def __format_as_steam(self) -> str: - return f"* {self.title} ([url={self.url}]{self.ref}[/url])" - - def __format_as_wiki(self) -> str: - if self.task_id: - return f"* {self.title} [{{{{BugReport|{self.task_id}}}}}]" - else: - return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]" - - def format(self, format: str) -> str: - """ - Format this line - - :attr format: the desired format. Possible values are 'text', 'steam' or 'html' - :type string: - """ - if format == 'html': - return self.__format_as_html() - elif format == 'steam': - return self.__format_as_steam() - elif format == 'wiki': - return self.__format_as_wiki() - else: - return self.__format_as_text() - - -def format_title(title: str) -> str: - title = title.strip() - if not title.endswith("."): - title = title + "." - return title - - -def extract_release_notes(version: str, task_id: int): - """ - Extract all release notes logs - - # Process - - 1. Retrieval of description of the given `task_id`. - 2. Find rows for the given `version` and convert to `ReleaseLogLine`. - 3. based on the associated task or commit retrieves the title of the log - line. - """ - phab = phabricator.Phabricator() - phab.update_interfaces() - task = phab.maniphest.info(task_id=task_id) - description = task["description"] - lines = description.split("\n") - start_index = lines.index(f"## Blender {version} ##") - lines = lines[start_index + 1:] - for line in lines: - if not line.strip(): - continue - if line.startswith("| **Report**"): - continue - if line.startswith("## Blender"): - break - - log_line = ReleaseLogLine(line) - if log_line.task_id: - issue_task = phab.maniphest.info(task_id=log_line.task_id) - log_line.title = format_title(issue_task.title) - yield log_line - elif log_line.commit_id: - commits = phab.diffusion.commit.search(constraints={"identifiers": [log_line.commit_id]}) - commit = commits.data[0] - commit_message = commit['fields']['message'] - commit_title = commit_message.split("\n")[0] - log_line.title = format_title(commit_title) - yield log_line - - -def print_release_notes(version: str, format: str, task_id: int): - """ - Generate and print the release notes to the console. - """ - if format == 'html': - print("
      ") - if format == 'steam': - print("[ul]") - for log_item in extract_release_notes(version=version, task_id=task_id): - print(log_item.format(format=format)) - if format == 'html': - print("
    ") - if format == 'steam': - print("[/ul]") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE) - parser.add_argument( - "--version", - required=True, - help="Version string in the form of {major}.{minor}.{build} (e.g. 2.83.7)") - parser.add_argument( - "--task", - required=True, - help="Phabricator ticket that is contains the release notes information (e.g. T77348)") - parser.add_argument( - "--format", - help="Format the result in `text`, `steam`, `wiki` or `html`", - default="text") - args = parser.parse_args() - - print_release_notes(version=args.version, format=args.format, task_id=int(args.task[1:])) +lts_issue.print_notes(version=version, format=args.format, issue=issue) diff --git a/release/lts/create_download_urls.py b/release/lts/lts_download.py old mode 100755 new mode 100644 similarity index 69% rename from release/lts/create_download_urls.py rename to release/lts/lts_download.py index c6b01acdf60..6d0dd81397b --- a/release/lts/create_download_urls.py +++ b/release/lts/lts_download.py @@ -1,14 +1,9 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later -import argparse import datetime -DESCRIPTION = ("This python script is used to generate the download urls " - "which we can copy-paste directly into the CMS of " - "www.blender.org") -USAGE = "create_download_urls --version=2.83.7" # Used date format: "September 30, 2020" DATE_FORMAT = "%B %d, %Y" @@ -62,19 +57,8 @@ def generate_html(version: Version) -> str: return "\n".join(lines) -def print_download_urls(version: Version): +def print_urls(version: str): """ Generate the download urls and print them to the console. """ - print(generate_html(version)) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE) - parser.add_argument("--version", - required=True, - help=("Version string in the form of {major}.{minor}." - "{build} (eg 2.83.7)")) - args = parser.parse_args() - - print_download_urls(version=Version(args.version)) + print(generate_html(Version(version))) diff --git a/release/lts/lts_issue.py b/release/lts/lts_issue.py new file mode 100644 index 00000000000..aa21b36423b --- /dev/null +++ b/release/lts/lts_issue.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later + +import requests + + +class ReleaseLogLine: + """ + Class containing the information of a single line of the release log + + Instance attributes: + + * line: (str) the original line used to create this log line + * issue_id: (int or None) the extracted issue id associated with this log + line. Can be None if the log line isn't associated with a issue. + * commit_id: (str or None) the extracted commit id associated with this log + line. Only filled when no `issue_id` could be found. + * ref: (str) `issue_id` or `commit_id` of this line, including `T` for issues + or `D` for diffs. + * title: (str) title of this log line. When constructed this attribute is + an empty string. The called needs to retrieve the title from the + backend. + * url: (str) url of the ticket issue or commit. + """ + + def __init__(self, line: str): + self.line = line + items = line.split("|") + self.issue_id = None + self.issue_repo = None + self.commit_id = None + self.commit_repo = None + base_url = "https://projects.blender.org" + try: + issue_tokens = items[1].strip().split("#") + if len(issue_tokens[0]) > 0: + self.issue_repo = issue_tokens[0] + self.issue_id = issue_tokens[1] + else: + self.issue_repo = "blender/blender" + self.issue_id = issue_tokens[1] + + self.ref = f"#{self.issue_id}" + self.url = f"{base_url}/{self.issue_repo}/issues/{self.issue_id}" + except IndexError: + # no issue + commit_string = items[3].strip() + commit_string = commit_string.split(",")[0] + commit_string = commit_string.split("]")[0] + commit_string = commit_string.replace("[", "") + + commit_tokens = commit_string.split("@") + if len(commit_tokens) > 1: + self.commit_repo = commit_tokens[0] + self.commit_id = commit_tokens[1] + else: + self.commit_repo = "blender/blender" + self.commit_id = commit_tokens[0] + + self.ref = f"{self.commit_id}" + self.url = f"{base_url}/{self.commit_repo}/commit/{self.commit_id}" + + self.title = "" + + def __format_as_html(self) -> str: + return f"
  • {self.title} [{self.ref}]
  • " + + def __format_as_text(self) -> str: + return f"* {self.title} [{self.ref}]" + + def __format_as_steam(self) -> str: + return f"* {self.title} ([url={self.url}]{self.ref}[/url])" + + def __format_as_wiki(self) -> str: + if self.issue_id: + return f"* {self.title} [{{{{BugReport|{self.issue_id}}}}}]" + else: + return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]" + + def format(self, format: str) -> str: + """ + Format this line + + :attr format: the desired format. Possible values are 'text', 'steam' or 'html' + :type string: + """ + if format == 'html': + return self.__format_as_html() + elif format == 'steam': + return self.__format_as_steam() + elif format == 'wiki': + return self.__format_as_wiki() + else: + return self.__format_as_text() + + +def format_title(title: str) -> str: + title = title.strip() + if not title.endswith("."): + title = title + "." + return title + + +def extract_release_notes(version: str, issue: str): + """ + Extract all release notes logs + + # Process + + 1. Retrieval of description of the given `issue_id`. + 2. Find rows for the given `version` and convert to `ReleaseLogLine`. + 3. based on the associated issue or commit retrieves the title of the log + line. + """ + base_url = "https://projects.blender.org/api/v1/repos" + issues_url = base_url + "/blender/blender/issues/" + headers = {'accept': 'application/json'} + + response = requests.get(issues_url + issue[1:], headers=headers) + description = response.json()["body"] + + lines = description.split("\n") + start_index = lines.index(f"## Blender {version}") + lines = lines[start_index + 1:] + for line in lines: + if not line.strip(): + continue + if line.startswith("| **Report**"): + continue + if line.startswith("## Blender"): + break + if line.find("| -- |") != -1: + continue + + log_line = ReleaseLogLine(line) + if log_line.issue_id: + issue_url = f"{base_url}/{log_line.issue_repo}/issues/{log_line.issue_id}" + response = requests.get(issue_url, headers=headers) + if response.status_code != 200: + raise ValueError("Issue not found: " + str(log_line.issue_id)) + + log_line.title = format_title(response.json()["title"]) + yield log_line + elif log_line.commit_id: + commit_url = f"{base_url}/{log_line.commit_repo}/git/commits/{log_line.commit_id}" + response = requests.get(commit_url, headers=headers) + if response.status_code != 200: + raise ValueError("Commit not found: " + log_line.commit_id) + + commit_message = response.json()['commit']['message'] + commit_title = commit_message.split("\n")[0] + log_line.title = format_title(commit_title) + yield log_line + + +def print_notes(version: str, format: str, issue: str): + """ + Generate and print the release notes to the console. + """ + if format == 'html': + print("
      ") + if format == 'steam': + print("[ul]") + for log_item in extract_release_notes(version=version, issue=issue): + print(log_item.format(format=format)) + if format == 'html': + print("
    ") + if format == 'steam': + print("[/ul]") diff --git a/release/lts/requirements.txt b/release/lts/requirements.txt index dc91ba85b01..f2293605cf1 100644 --- a/release/lts/requirements.txt +++ b/release/lts/requirements.txt @@ -1 +1 @@ -phabricator==0.7.0 \ No newline at end of file +requests diff --git a/release/scripts/freestyle/modules/freestyle/chainingiterators.py b/release/scripts/freestyle/modules/freestyle/chainingiterators.py index 656a5b09a37..fbe419293ca 100644 --- a/release/scripts/freestyle/modules/freestyle/chainingiterators.py +++ b/release/scripts/freestyle/modules/freestyle/chainingiterators.py @@ -286,7 +286,7 @@ class pySketchyChainingIterator(ChainingIterator): if not found: # This is a fatal error condition: self.current_edge must be found - # among the edges seen by the AdjacencyIterator [bug T35695]. + # among the edges seen by the AdjacencyIterator [bug #35695]. if bpy.app.debug_freestyle: print('pySketchyChainingIterator: current edge not found') return None diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 9d820b8c9de..f37d8150ae5 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -487,7 +487,7 @@ def disable_all(): def _blender_manual_url_prefix(): - return "https://docs.blender.org/manual/en/%d.%d" % _bpy.app.version[:2] + return "https://docs.blender.org/manual/%s/%d.%d" % (_bpy.utils.manual_language_code(), *_bpy.app.version[:2]) def module_bl_info(mod, *, info_basis=None): diff --git a/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py b/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py index 7aff3596c42..d2d00238ddf 100644 --- a/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py +++ b/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py @@ -113,7 +113,7 @@ def expand(line, cursor, namespace, *, private=True): if len(matches) == 1: scrollback = '' else: - # causes blender bug T27495 since string keys may contain '.' + # causes blender bug #27495 since string keys may contain '.' # scrollback = ' '.join([m.split('.')[-1] for m in matches]) # add white space to align with the cursor diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py index cb6ea0318a4..4295aa5f237 100644 --- a/release/scripts/modules/bpy/ops.py +++ b/release/scripts/modules/bpy/ops.py @@ -32,7 +32,7 @@ class _BPyOpsSubModOp: # XXX You never quite know what you get from bpy.types, # with operators... Operator and OperatorProperties # are shadowing each other, and not in the same way for - # native ops and py ones! See T39158. + # native ops and py ones! See #39158. # op_class = getattr(bpy.types, idname) op_class = _op_get_rna_type(idname) descr = op_class.description diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index 22577dbd1cf..c86e97153aa 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -26,6 +26,7 @@ __all__ = ( "register_tool", "make_rna_paths", "manual_map", + "manual_language_code", "previews", "resource_path", "script_path_user", @@ -1002,11 +1003,11 @@ def unregister_tool(tool_cls): # we start with the built-in default mapping def _blender_default_map(): - import rna_manual_reference as ref_mod - ret = (ref_mod.url_manual_prefix, ref_mod.url_manual_mapping) - # avoid storing in memory - del _sys.modules["rna_manual_reference"] - return ret + # NOTE(@ideasman42): Avoid importing this as there is no need to keep the lookup table in memory. + # As this runs when the user accesses the "Online Manual", the overhead loading the file is acceptable. + # In my tests it's under 1/100th of a second loading from a `pyc`. + ref_mod = execfile(_os.path.join(_script_base_dir, "modules", "rna_manual_reference.py")) + return (ref_mod.url_manual_prefix, ref_mod.url_manual_mapping) # hooks for doc lookups @@ -1035,6 +1036,53 @@ def manual_map(): yield prefix, url_manual_mapping +# Languages which are supported by the user manual (commented when there is no translation). +_manual_language_codes = { + "ar_EG": "ar", # Arabic + # "bg_BG": "bg", # Bulgarian + # "ca_AD": "ca", # Catalan + # "cs_CZ": "cz", # Czech + "de_DE": "de", # German + # "el_GR": "el", # Greek + "es": "es", # Spanish + "fi_FI": "fi", # Finnish + "fr_FR": "fr", # French + "id_ID": "id", # Indonesian + "it_IT": "it", # Italian + "ja_JP": "ja", # Japanese + "ko_KR": "ko", # Korean + # "nb": "nb", # Norwegian + # "nl_NL": "nl", # Dutch + # "pl_PL": "pl", # Polish + "pt_PT": "pt", # Portuguese + # Portuguese - Brazil, for until we have a pt_BR version. + "pt_BR": "pt", + "ru_RU": "ru", # Russian + "sk_SK": "sk", # Slovak + # "sl": "sl", # Slovenian + "sr_RS": "sr", # Serbian + # "sv_SE": "sv", # Swedish + # "tr_TR": "th", # Thai + "uk_UA": "uk", # Ukrainian + "vi_VN": "vi", # Vietnamese + "zh_CN": "zh-hans", # Simplified Chinese + "zh_TW": "zh-hant", # Traditional Chinese +} + + +def manual_language_code(default="en"): + """ + :return: + The language code used for user manual URL component based on the current language user-preference, + falling back to the ``default`` when unavailable. + :rtype: str + """ + language = _bpy.context.preferences.view.language + if language == 'DEFAULT': + language = _os.getenv("LANG", "").split(".")[0] + return _manual_language_codes.get(language, default) + + # Build an RNA path from struct/property/enum names. def make_rna_paths(struct_name, prop_name, enum_name): """ diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index 3b90b18359e..9bd5d9a83fa 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -259,15 +259,15 @@ def bake_action_iter( if is_new_action: action = bpy.data.actions.new("Action") - # Only leave tweak mode if we actually need to modify the action (T57159) + # Only leave tweak mode if we actually need to modify the action (#57159) if action != atd.action: - # Leave tweak mode before trying to modify the action (T48397) + # Leave tweak mode before trying to modify the action (#48397) if atd.use_tweak_mode: atd.use_tweak_mode = False atd.action = action - # Baking the action only makes sense in Replace mode, so force it (T69105) + # Baking the action only makes sense in Replace mode, so force it (#69105) if not atd.use_tweak_mode: atd.action_blend_type = 'REPLACE' diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py index 04b536fce40..794c39e07dc 100644 --- a/release/scripts/modules/bpy_extras/io_utils.py +++ b/release/scripts/modules/bpy_extras/io_utils.py @@ -111,7 +111,7 @@ def orientation_helper(axis_forward='Y', axis_up='Z'): """ def wrapper(cls): # Without that, we may end up adding those fields to some **parent** class' __annotations__ property - # (like the ImportHelper or ExportHelper ones)! See T58772. + # (like the ImportHelper or ExportHelper ones)! See #58772. if "__annotations__" not in cls.__dict__: setattr(cls, "__annotations__", {}) diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index d8d6a9123f2..18dbab7c624 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -564,7 +564,7 @@ class Mesh(bpy_types.ID): face_lengths = tuple(map(len, faces)) - # NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: T90268. + # NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: #90268. vertices_len = len(vertices) edges_len = len(edges) faces_len = len(faces) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index fd7b7dbb786..a3654b12c20 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -4,38 +4,10 @@ # autopep8: off import bpy -manual_version = '%d.%d' % bpy.app.version[:2] - -url_manual_prefix = "https://docs.blender.org/manual/en/" + manual_version + "/" - -language = bpy.context.preferences.view.language -if language == 'DEFAULT': - import os - language = os.getenv('LANG', '').split('.')[0] - -LANG = { -"ar_EG": "ar", -"de_DE": "de", -"es": "es", -"fi_FI": "fi", -"fr_FR": "fr", -"id_ID": "id", -"it_IT": "it", -"ja_JP": "ja", -"ko_KR": "ko", -"pt_PT": "pt", -"pt_BR": "pt", -"ru_RU": "ru", -"sk_SK": "sk", -"sr_RS": "sr", -"uk_UA": "uk", -"vi_VN": "vi", -"zh_CN": "zh-hans", -"zh_TW": "zh-hant", -}.get(language) - -if LANG is not None: - url_manual_prefix = url_manual_prefix.replace("manual/en", "manual/" + LANG) +url_manual_prefix = "https://docs.blender.org/manual/%s/%d.%d/" % ( + bpy.utils.manual_language_code(), + *bpy.app.version[:2], +) url_manual_mapping = ( ("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"), @@ -641,7 +613,6 @@ url_manual_mapping = ( ("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"), ("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"), ("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"), - ("bpy.types.brush.html#bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-html-bpy-types-brush-jitter"), ("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"), ("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"), ("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"), @@ -672,7 +643,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/read/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"), ("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/read/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"), ("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/read/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"), - ("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"), + ("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_group_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"), ("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"), ("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"), ("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"), @@ -1417,6 +1388,7 @@ url_manual_mapping = ( ("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"), ("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"), ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"), + ("bpy.types.geometrynodeblurattribute*", "modeling/geometry_nodes/attribute/blur_attribute.html#bpy-types-geometrynodeblurattribute"), ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), ("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"), ("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"), @@ -2055,7 +2027,6 @@ url_manual_mapping = ( ("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"), ("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"), ("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"), - ("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"), ("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"), ("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"), ("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"), @@ -2111,7 +2082,6 @@ url_manual_mapping = ( ("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/operations/bounding_box.html#bpy-types-geometrynodeboundbox"), ("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve/primitives/arc.html#bpy-types-geometrynodecurvearc"), ("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/operations/dual_mesh.html#bpy-types-geometrynodedualmesh"), - ("bpy.types.geometrynodematerial*", "-1"), ("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh/primitives/cone.html#bpy-types-geometrynodemeshcone"), ("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh/primitives/cube.html#bpy-types-geometrynodemeshcube"), ("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh/primitives/grid.html#bpy-types-geometrynodemeshgrid"), diff --git a/release/scripts/presets/keyconfig/Blender.py b/release/scripts/presets/keyconfig/Blender.py index e77fde4c39c..52e4c2d4229 100644 --- a/release/scripts/presets/keyconfig/Blender.py +++ b/release/scripts/presets/keyconfig/Blender.py @@ -86,7 +86,7 @@ class Prefs(bpy.types.KeyConfigPreferences): update=update_fn, ) - # Experimental: only show with developer extras, see: T96544. + # Experimental: only show with developer extras, see: #96544. use_tweak_select_passthrough: BoolProperty( name="Tweak Select: Mouse Select & Move", description=( @@ -96,7 +96,7 @@ class Prefs(bpy.types.KeyConfigPreferences): default=False, update=update_fn, ) - # Experimental: only show with developer extras, see: T96544. + # Experimental: only show with developer extras, see: #96544. use_tweak_tool_lmb_interaction: BoolProperty( name="Tweak Tool: Left Mouse Select & Move", description=( diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 68fb337f9a4..e18461eb4df 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -37,7 +37,7 @@ class Params: # instead be bound to a binding that doesn't de-select all, this way: # - Click-drag moves the current selection. # - Click selects only the item at the cursor position. - # See: T97032. + # See: #97032. "use_tweak_select_passthrough", "use_tweak_tool_lmb_interaction", "use_mouse_emulate_3_button", @@ -465,7 +465,7 @@ def _template_items_tool_select( fallback=False, ): if not params.legacy and not fallback: - # Experimental support for LMB interaction for the tweak tool. see: T96544. + # Experimental support for LMB interaction for the tweak tool. see: #96544. # NOTE: For RMB-select this is a much bigger change as it disables 3D cursor placement on LMB. # For LMB-select this means an LMB -drag will not first de-select all (similar to node/graph editor). select_passthrough = False @@ -498,7 +498,7 @@ def _template_items_tool_select( {"properties": [("toggle", True), *operator_props]}), # Fallback key-map must transform as the primary tool is expected - # to be accessed via gizmos in this case. See: T96885. + # to be accessed via gizmos in this case. See: #96885. *(() if not fallback else ( ("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, {"properties": [("release_confirm", True)]}), @@ -3478,7 +3478,8 @@ def km_animation_channels(params): # Selection. *_template_items_select_actions(params, "anim.channels_select_all"), ("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None), - ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, None), + ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, + {"properties": [("extend", False)]}), ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True}, {"properties": [("extend", True)]}), ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True}, @@ -4729,7 +4730,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None): # NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used - # as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See T92467. + # as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See #92467. props_vert_without_handles = () if select_passthrough: @@ -5627,6 +5628,7 @@ def km_curves(params): ("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None), ("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None), *_template_items_select_actions(params, "curves.select_all"), + ("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ]) return keymap @@ -5681,7 +5683,7 @@ def km_object_non_modal(params): ]) else: items.extend([ - # NOTE: this shortcut (while not temporary) is not ideal, see: T89757. + # NOTE: this shortcut (while not temporary) is not ideal, see: #89757. ("object.transfer_mode", {"type": 'Q', "value": 'PRESS', "alt": True}, None), ]) @@ -6344,6 +6346,8 @@ def km_node_link_modal_map(_params): return keymap # Fallback for gizmos that don't have custom a custom key-map. + + def km_generic_gizmo(_params): keymap = ( "Generic Gizmo", diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 6a130edbb38..810c40cb687 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -790,7 +790,7 @@ class TransformsToDeltasAnim(Operator): continue # first pass over F-Curves: ensure that we don't have conflicting - # transforms already (e.g. if this was applied already) T29110. + # transforms already (e.g. if this was applied already) #29110. existingFCurves = {} for fcu in adt.action.fcurves: # get "delta" path - i.e. the final paths which may clash diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index dc8504c057e..d0134bd076f 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -700,7 +700,7 @@ class PREFERENCES_OT_addon_install(Operator): addons_new.discard("modules") # disable any addons we may have enabled previously and removed. - # this is unlikely but do just in case. bug T23978. + # this is unlikely but do just in case. bug #23978. for new_addon in addons_new: addon_utils.disable(new_addon, default_set=True) diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index ca309bff9e4..6d1d0f1be99 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -581,7 +581,7 @@ class LightMapPack(Operator): # Proper solution would be to make undo stack aware of such things, # but for now just disable redo. Keep undo here so unwanted changes to uv # coords might be undone. - # This fixes infinite image creation reported there T30968 (sergey) + # This fixes infinite image creation reported there #30968 (sergey) bl_options = {'UNDO'} PREF_CONTEXT: bpy.props.EnumProperty( diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py index 616e37d37e7..0b948fa2763 100644 --- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py +++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py @@ -90,7 +90,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, tone_range = max_tone - min_tone if tone_range < 0.0001: - # weak, don't cancel, see T43345 + # weak, don't cancel, see #43345 tone_range = 0.0 else: tone_range = 1.0 / tone_range diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index bb0d163fdd6..6eee0ef84f0 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -42,7 +42,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator): bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN') # ignore return from operators above because they are 'RUNNING_MODAL', - # and cause this one not to be freed. T24671. + # and cause this one not to be freed. #24671. return {'FINISHED'} def invoke(self, context, _event): @@ -104,7 +104,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): 'INVOKE_REGION_WIN', TRANSFORM_OT_translate={ # Don't set the constraint axis since users will expect MMB - # to use the user setting, see: T61637 + # to use the user setting, see: #61637 # "orient_type": 'NORMAL', # Not a popular choice, too restrictive for retopo. # "constraint_axis": (True, True, False)}) @@ -114,7 +114,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN') # ignore return from operators above because they are 'RUNNING_MODAL', - # and cause this one not to be freed. T24671. + # and cause this one not to be freed. #24671. return {'FINISHED'} def execute(self, context): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index e82694249fd..67858e53b62 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1056,7 +1056,7 @@ class WM_OT_url_open_preset(Operator): return "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2] def _url_from_manual(self, _context): - return "https://docs.blender.org/manual/en/%d.%d/" % bpy.app.version[:2] + return "https://docs.blender.org/manual/%s/%d.%d/" % (bpy.utils.manual_language_code(), *bpy.app.version[:2]) def _url_from_api(self, _context): return "https://docs.blender.org/api/%d.%d/" % bpy.app.version[:2] @@ -1725,7 +1725,7 @@ class WM_OT_properties_edit(Operator): for nt in adt.nla_tracks: _update_strips(nt.strips) - # Otherwise existing buttons which reference freed memory may crash Blender (T26510). + # Otherwise existing buttons which reference freed memory may crash Blender (#26510). for win in context.window_manager.windows: for area in win.screen.areas: area.tag_redraw() diff --git a/release/scripts/startup/bl_ui/node_add_menu.py b/release/scripts/startup/bl_ui/node_add_menu.py index 873dbd533a5..a0dad139243 100644 --- a/release/scripts/startup/bl_ui/node_add_menu.py +++ b/release/scripts/startup/bl_ui/node_add_menu.py @@ -35,19 +35,10 @@ def draw_node_group_add_menu(context, layout): if node_tree: from nodeitems_builtins import node_tree_group_type - def contains_group(nodetree, group): - if nodetree == group: - return True - for node in nodetree.nodes: - if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None: - if contains_group(node.node_tree, group): - return True - return False - groups = [ group for group in context.blend_data.node_groups if (group.bl_idname == node_tree.bl_idname and - not contains_group(group, node_tree) and + not group.contains_tree(node_tree) and not group.name.startswith('.')) ] if groups: diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py index b829795a232..43fd87d0f83 100644 --- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py +++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py @@ -338,6 +338,7 @@ class NODE_MT_geometry_node_GEO_MESH_READ(Menu): node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle") node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors") node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices") + node_add_menu.add_node_type(layout, "GeometryNodeEdgesToFaceGroups") node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea") node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors") node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries") diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index 272191aebe5..02e066161b6 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -140,7 +140,7 @@ class DATA_PT_EEVEE_light_distance(DataButtonsPanel, Panel): class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel): bl_label = "Shadow" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'} @classmethod def poll(cls, context): @@ -168,7 +168,8 @@ class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel): if light.type != 'SUN': sub.prop(light, "shadow_buffer_clip_start", text="Clip Start") - col.prop(light, "shadow_buffer_bias", text="Bias") + if context.engine != 'BLENDER_EEVEE_NEXT': + col.prop(light, "shadow_buffer_bias", text="Bias") class DATA_PT_EEVEE_shadow_cascaded_shadow_map(DataButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 1ff76a73e7e..8e09a64b915 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -485,7 +485,6 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): layout.use_property_split = True layout.use_property_decorate = False - obj = context.object me = context.mesh col = layout.column() diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index cbe6b9f3e6d..01d2e08bc4f 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -62,7 +62,6 @@ class PARTICLE_MT_context_menu(Menu): def draw(self, context): layout = self.layout psys = context.particle_system - experimental = context.preferences.experimental props = layout.operator( "particle.copy_particle_systems", @@ -508,7 +507,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel): sub.prop(psys.settings, "bending_random", text="Random") col.prop(cloth, "bending_damping", text="Damping") # XXX has no noticeable effect with stiff hair structure springs - #col.prop(cloth, "spring_damping", text="Damping") + # col.prop(cloth, "spring_damping", text="Damping") class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): @@ -1100,7 +1099,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): if part.physics_type == 'KEYED': col = layout.column() # doesn't work yet - #col.alert = key.valid + # col.alert = key.valid col.prop(key, "object") col.prop(key, "system", text="System") sub = col.column(align=True) @@ -1110,7 +1109,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): elif part.physics_type == 'BOIDS': sub = layout.column() # doesn't work yet - #sub.alert = key.valid + # sub.alert = key.valid sub.prop(key, "object") sub.prop(key, "system", text="System") layout.prop(key, "alliance") @@ -1157,7 +1156,7 @@ class PARTICLE_PT_physics_fluid_interaction(ParticleButtonsPanel, Panel): if key: sub = layout.column() # doesn't work yet - #sub.alert = key.valid + # sub.alert = key.valid sub.prop(key, "object") sub.prop(key, "system", text="System") diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 2296d7ad157..bf3c322f377 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -460,6 +460,32 @@ class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel): col.prop(props, "light_threshold") +class RENDER_PT_eevee_next_shadows(RenderButtonsPanel, Panel): + bl_label = "Shadows" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + scene = context.scene + props = scene.eevee + self.layout.prop(props, "use_shadows", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.eevee + + col = layout.column() + col.prop(props, "shadow_pool_size", text="Pool Size") + col.prop(props, "light_threshold") + + class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel): bl_label = "Sampling" COMPAT_ENGINES = {'BLENDER_EEVEE'} @@ -615,7 +641,6 @@ class RENDER_PT_eevee_next_film(RenderButtonsPanel, Panel): scene = context.scene rd = scene.render - props = scene.eevee col = layout.column() col.prop(rd, "filter_size") @@ -808,6 +833,10 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel): col = flow.column() col.prop(rd, "simplify_volumes", text="Volume Resolution") + if context.engine in 'BLENDER_EEVEE_NEXT': + col = flow.column() + col.prop(rd, "simplify_shadows", text="Shadow Resolution") + class RENDER_PT_simplify_render(RenderButtonsPanel, Panel): bl_label = "Render" @@ -835,6 +864,10 @@ class RENDER_PT_simplify_render(RenderButtonsPanel, Panel): col = flow.column() col.prop(rd, "simplify_child_particles_render", text="Max Child Particles") + if context.engine in 'BLENDER_EEVEE_NEXT': + col = flow.column() + col.prop(rd, "simplify_shadows_render", text="Shadow Resolution") + class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSimplifyPanel): bl_label = "Grease Pencil" @@ -869,6 +902,7 @@ classes = ( RENDER_PT_eevee_performance, RENDER_PT_eevee_hair, RENDER_PT_eevee_shadows, + RENDER_PT_eevee_next_shadows, RENDER_PT_eevee_indirect_lighting, RENDER_PT_eevee_indirect_lighting_display, RENDER_PT_eevee_film, diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 8abd8b61839..4d97fe9cf62 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -91,7 +91,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel, Panel): else: layout.template_preview(tex, slot=slot) - # Show Alpha Button for Brush Textures, see T29502. + # Show Alpha Button for Brush Textures, see #29502. idblock = context_tex_datablock(context) if isinstance(idblock, Brush): layout.prop(tex, "use_preview_alpha") diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 7e221d63d4a..c54dea94318 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -62,7 +62,7 @@ class NODE_HT_header(Header): types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'GPENCIL', 'VOLUME', 'CURVES', 'POINTCLOUD'} - # disable material slot buttons when pinned, cannot find correct slot within id_from (T36589) + # disable material slot buttons when pinned, cannot find correct slot within id_from (#36589) # disable also when the selected object does not support materials has_material_slots = not snode.pin and ob_type in types_that_support_material diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 8b08ec99d89..cae06add9ef 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -407,7 +407,7 @@ class SEQUENCER_MT_view(Menu): if st.view_type == 'PREVIEW': # Specifying the REGION_PREVIEW context is needed in preview-only # mode, else the lookup for the shortcut will fail in - # wm_keymap_item_find_props() (see T32595). + # wm_keymap_item_find_props() (see #32595). layout.operator_context = 'INVOKE_REGION_PREVIEW' layout.prop(st, "show_region_ui") layout.prop(st, "show_region_tool_header") @@ -429,7 +429,7 @@ class SEQUENCER_MT_view(Menu): layout.operator_context = 'INVOKE_REGION_WIN' if st.view_type == 'PREVIEW': - # See above (T32595) + # See above (#32595) layout.operator_context = 'INVOKE_REGION_PREVIEW' layout.operator("sequencer.view_selected", text="Frame Selected") @@ -1996,7 +1996,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel): split = col.split(factor=0.4) split.alignment = 'RIGHT' - split.label(text="Pan", heading_ctxt=i18n_contexts.id_sound) + split.label(text="Pan", text_ctxt=i18n_contexts.id_sound) split.prop(strip, "pan", text="") split.enabled = pan_enabled diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 37cb01503d3..533d0976af0 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -25,14 +25,15 @@ def kmi_to_string_or_none(kmi): def generate_from_enum_ex( - _context, *, - idname_prefix, - icon_prefix, - type, - attr, - cursor='DEFAULT', - tooldef_keywords={}, - exclude_filter={}, + _context, + *, + idname_prefix, + icon_prefix, + type, + attr, + cursor="DEFAULT", + tooldef_keywords={}, + exclude_filter={}, ): tool_defs = [] for enum in type.bl_rna.properties[attr].enum_items_static: @@ -78,12 +79,11 @@ class _defs_view3d_generic: props = tool.operator_properties("view3d.cursor3d") layout.prop(props, "use_depth") layout.prop(props, "orientation") + return dict( idname="builtin.cursor", label="Cursor", - description=( - "Set the cursor location, drag to transform" - ), + description=("Set the cursor location, drag to transform"), icon="ops.generic.cursor", keymap="3D View Tool: Cursor", draw_settings=draw_settings, @@ -118,6 +118,7 @@ class _defs_view3d_generic: kmi_to_string_or_none(kmi_add), kmi_to_string_or_none(kmi_remove), ) + return dict( idname="builtin.measure", label="Measure", @@ -129,7 +130,6 @@ class _defs_view3d_generic: class _defs_annotate: - def draw_settings_common(context, layout, tool): gpd = context.annotation_data region_type = context.region.type @@ -139,15 +139,15 @@ class _defs_annotate: text = gpd.layers.active_note maxw = 25 if len(text) > maxw: - text = text[:maxw - 5] + '..' + text[-3:] + text = text[: maxw - 5] + ".." + text[-3:] else: text = "" gpl = context.active_annotation_layer if gpl is not None: layout.label(text="Annotation:") - if context.space_data.type in {'VIEW_3D', 'SEQUENCE_EDITOR'}: - if region_type == 'TOOL_HEADER': + if context.space_data.type in {"VIEW_3D", "SEQUENCE_EDITOR"}: + if region_type == "TOOL_HEADER": sub = layout.split(align=True, factor=0.5) sub.ui_units_x = 6.5 sub.prop(gpl, "color", text="") @@ -164,21 +164,30 @@ class _defs_annotate: space_type = tool.space_type tool_settings = context.tool_settings - if space_type == 'VIEW_3D': + if space_type == "VIEW_3D": row = layout.row(align=True) - row.prop(tool_settings, "annotation_stroke_placement_view3d", text="Placement") - if tool_settings.gpencil_stroke_placement_view3d == 'CURSOR': + row.prop( + tool_settings, "annotation_stroke_placement_view3d", text="Placement" + ) + if tool_settings.gpencil_stroke_placement_view3d == "CURSOR": row.prop(tool_settings.gpencil_sculpt, "lockaxis") - elif tool_settings.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}: + elif tool_settings.gpencil_stroke_placement_view3d in {"SURFACE", "STROKE"}: row.prop(tool_settings, "use_gpencil_stroke_endpoints") - elif space_type in {'IMAGE_EDITOR', 'NODE_EDITOR', 'SEQUENCE_EDITOR', 'CLIP_EDITOR'}: + elif space_type in { + "IMAGE_EDITOR", + "NODE_EDITOR", + "SEQUENCE_EDITOR", + "CLIP_EDITOR", + }: row = layout.row(align=True) - row.prop(tool_settings, "annotation_stroke_placement_view2d", text="Placement") + row.prop( + tool_settings, "annotation_stroke_placement_view2d", text="Placement" + ) if tool.idname == "builtin.annotate_line": props = tool.operator_properties("gpencil.annotate") - if region_type == 'TOOL_HEADER': + if region_type == "TOOL_HEADER": row = layout.row() row.ui_units_x = 15 row.prop(props, "arrowstyle_start", text="Start") @@ -190,7 +199,7 @@ class _defs_annotate: col.prop(props, "arrowstyle_end", text="End") elif tool.idname == "builtin.annotate": props = tool.operator_properties("gpencil.annotate") - if region_type == 'TOOL_HEADER': + if region_type == "TOOL_HEADER": row = layout.row() row.prop(props, "use_stabilizer", text="Stabilize Stroke") subrow = layout.row(align=False) @@ -210,10 +219,10 @@ class _defs_annotate: idname="builtin.annotate", label="Annotate", icon="ops.gpencil.draw", - cursor='PAINT_BRUSH', + cursor="PAINT_BRUSH", keymap="Generic Tool: Annotate", draw_settings=draw_settings, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) @ToolDef.from_fn.with_args(draw_settings=draw_settings_common) @@ -222,10 +231,10 @@ class _defs_annotate: idname="builtin.annotate_line", label="Annotate Line", icon="ops.gpencil.draw.line", - cursor='PAINT_BRUSH', + cursor="PAINT_BRUSH", keymap="Generic Tool: Annotate Line", draw_settings=draw_settings, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) @ToolDef.from_fn.with_args(draw_settings=draw_settings_common) @@ -234,10 +243,10 @@ class _defs_annotate: idname="builtin.annotate_polygon", label="Annotate Polygon", icon="ops.gpencil.draw.poly", - cursor='PAINT_BRUSH', + cursor="PAINT_BRUSH", keymap="Generic Tool: Annotate Polygon", draw_settings=draw_settings, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) @ToolDef.from_fn @@ -246,21 +255,21 @@ class _defs_annotate: # TODO: Move this setting to tool_settings prefs = context.preferences layout.prop(prefs.edit, "grease_pencil_eraser_radius", text="Radius") + return dict( idname="builtin.annotate_eraser", label="Annotate Eraser", icon="ops.gpencil.draw.eraser", - cursor='ERASER', + cursor="ERASER", keymap="Generic Tool: Annotate Eraser", draw_settings=draw_settings, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) class _defs_transform: - def draw_transform_sculpt_tool_settings(context, layout): - if context.mode != 'SCULPT': + if context.mode != "SCULPT": return layout.prop(context.tool_settings.sculpt, "transform_mode") @@ -268,7 +277,10 @@ class _defs_transform: def translate(): def draw_settings(context, layout, _tool): _defs_transform.draw_transform_sculpt_tool_settings(context, layout) - _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1) + _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index( + context, layout, 1 + ) + return dict( idname="builtin.move", label="Move", @@ -284,7 +296,10 @@ class _defs_transform: def rotate(): def draw_settings(context, layout, _tool): _defs_transform.draw_transform_sculpt_tool_settings(context, layout) - _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 2) + _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index( + context, layout, 2 + ) + return dict( idname="builtin.rotate", label="Rotate", @@ -300,7 +315,10 @@ class _defs_transform: def scale(): def draw_settings(context, layout, _tool): _defs_transform.draw_transform_sculpt_tool_settings(context, layout) - _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 3) + _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index( + context, layout, 3 + ) + return dict( idname="builtin.scale", label="Scale", @@ -315,7 +333,10 @@ class _defs_transform: @ToolDef.from_fn def scale_cage(): def draw_settings(context, layout, _tool): - _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 3) + _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index( + context, layout, 3 + ) + return dict( idname="builtin.scale_cage", label="Scale Cage", @@ -330,7 +351,10 @@ class _defs_transform: def shear(): def draw_settings(context, layout, _tool): # props = tool.operator_properties("transform.shear") - _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 2) + _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index( + context, layout, 2 + ) + return dict( idname="builtin.shear", label="Shear", @@ -348,7 +372,7 @@ class _defs_transform: show_drag = True tool_settings = context.tool_settings - if tool_settings.workspace_tool_type == 'FALLBACK': + if tool_settings.workspace_tool_type == "FALLBACK": show_drag = False if show_drag: @@ -356,14 +380,14 @@ class _defs_transform: layout.prop(props, "drag_action") _defs_transform.draw_transform_sculpt_tool_settings(context, layout) - _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1) + _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index( + context, layout, 1 + ) return dict( idname="builtin.transform", label="Transform", - description=( - "Supports any combination of grab, rotate, and scale at once" - ), + description=("Supports any combination of grab, rotate, and scale at once"), icon="ops.transform.transform", widget="VIEW3D_GGT_xform_gizmo", keymap="3D View Tool: Transform", @@ -372,7 +396,6 @@ class _defs_transform: class _defs_view3d_select: - @ToolDef.from_fn def select(): return dict( @@ -390,6 +413,7 @@ class _defs_view3d_select: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) + return dict( idname="builtin.select_box", label="Select Box", @@ -406,6 +430,7 @@ class _defs_view3d_select: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) + return dict( idname="builtin.select_lasso", label="Select Lasso", @@ -426,6 +451,7 @@ class _defs_view3d_select: def draw_cursor(_context, tool, xy): from gpu_extras.presets import draw_circle_2d + props = tool.operator_properties("view3d.select_circle") radius = props.radius draw_circle_2d(xy, (1.0,) * 4, radius, segments=32) @@ -442,7 +468,6 @@ class _defs_view3d_select: class _defs_view3d_add: - @staticmethod def description_interactive_add(context, _item, _km, *, prefix): km = context.window_manager.keyconfigs.user.keymaps["View3D Placement Modal"] @@ -453,9 +478,9 @@ class _defs_view3d_add: return item if km is not None: - kmi_snap = keymap_item_from_propvalue('SNAP_ON') - kmi_center = keymap_item_from_propvalue('PIVOT_CENTER_ON') - kmi_fixed_aspect = keymap_item_from_propvalue('FIXED_ASPECT_ON') + kmi_snap = keymap_item_from_propvalue("SNAP_ON") + kmi_center = keymap_item_from_propvalue("PIVOT_CENTER_ON") + kmi_fixed_aspect = keymap_item_from_propvalue("FIXED_ASPECT_ON") else: kmi_snap = None kmi_center = None @@ -490,7 +515,7 @@ class _defs_view3d_add: row = layout.row() row.prop(props, "snap_target") - region_is_header = bpy.context.region.type == 'TOOL_HEADER' + region_is_header = bpy.context.region.type == "TOOL_HEADER" if region_is_header: # Don't draw the "extra" popover here as we might have other settings & this should be last. @@ -514,7 +539,9 @@ class _defs_view3d_add: @ToolDef.from_fn def cube_add(): def draw_settings(_context, layout, tool, *, extra=False): - show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra) + show_extra = _defs_view3d_add.draw_settings_interactive_add( + layout, tool, extra + ) if show_extra: layout.popover("TOPBAR_PT_tool_settings_extra", text="...") @@ -523,7 +550,8 @@ class _defs_view3d_add: label="Add Cube", icon="ops.mesh.primitive_cube_add_gizmo", description=lambda *args: _defs_view3d_add.description_interactive_add( - *args, prefix=tip_("Add cube to mesh interactively"), + *args, + prefix=tip_("Add cube to mesh interactively"), ), widget="VIEW3D_GGT_placement", keymap="3D View Tool: Object, Add Primitive", @@ -533,7 +561,9 @@ class _defs_view3d_add: @ToolDef.from_fn def cone_add(): def draw_settings(_context, layout, tool, *, extra=False): - show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra) + show_extra = _defs_view3d_add.draw_settings_interactive_add( + layout, tool, extra + ) if extra: return @@ -549,7 +579,8 @@ class _defs_view3d_add: label="Add Cone", icon="ops.mesh.primitive_cone_add_gizmo", description=lambda *args: _defs_view3d_add.description_interactive_add( - *args, prefix=tip_("Add cone to mesh interactively"), + *args, + prefix=tip_("Add cone to mesh interactively"), ), widget="VIEW3D_GGT_placement", keymap="3D View Tool: Object, Add Primitive", @@ -559,7 +590,9 @@ class _defs_view3d_add: @ToolDef.from_fn def cylinder_add(): def draw_settings(_context, layout, tool, *, extra=False): - show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra) + show_extra = _defs_view3d_add.draw_settings_interactive_add( + layout, tool, extra + ) if extra: return @@ -569,12 +602,14 @@ class _defs_view3d_add: if show_extra: layout.popover("TOPBAR_PT_tool_settings_extra", text="...") + return dict( idname="builtin.primitive_cylinder_add", label="Add Cylinder", icon="ops.mesh.primitive_cylinder_add_gizmo", description=lambda *args: _defs_view3d_add.description_interactive_add( - *args, prefix=tip_("Add cylinder to mesh interactively"), + *args, + prefix=tip_("Add cylinder to mesh interactively"), ), widget="VIEW3D_GGT_placement", keymap="3D View Tool: Object, Add Primitive", @@ -584,7 +619,9 @@ class _defs_view3d_add: @ToolDef.from_fn def uv_sphere_add(): def draw_settings(_context, layout, tool, *, extra=False): - show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra) + show_extra = _defs_view3d_add.draw_settings_interactive_add( + layout, tool, extra + ) if extra: return @@ -594,12 +631,14 @@ class _defs_view3d_add: if show_extra: layout.popover("TOPBAR_PT_tool_settings_extra", text="...") + return dict( idname="builtin.primitive_uv_sphere_add", label="Add UV Sphere", icon="ops.mesh.primitive_sphere_add_gizmo", description=lambda *args: _defs_view3d_add.description_interactive_add( - *args, prefix=tip_("Add sphere to mesh interactively"), + *args, + prefix=tip_("Add sphere to mesh interactively"), ), widget="VIEW3D_GGT_placement", keymap="3D View Tool: Object, Add Primitive", @@ -609,7 +648,9 @@ class _defs_view3d_add: @ToolDef.from_fn def ico_sphere_add(): def draw_settings(_context, layout, tool, *, extra=False): - show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra) + show_extra = _defs_view3d_add.draw_settings_interactive_add( + layout, tool, extra + ) if extra: return @@ -618,12 +659,14 @@ class _defs_view3d_add: if show_extra: layout.popover("TOPBAR_PT_tool_settings_extra", text="...") + return dict( idname="builtin.primitive_ico_sphere_add", label="Add Ico Sphere", icon="ops.mesh.primitive_sphere_add_gizmo", description=lambda *args: _defs_view3d_add.description_interactive_add( - *args, prefix=tip_("Add sphere to mesh interactively"), + *args, + prefix=tip_("Add sphere to mesh interactively"), ), widget="VIEW3D_GGT_placement", keymap="3D View Tool: Object, Add Primitive", @@ -634,8 +677,8 @@ class _defs_view3d_add: # ----------------------------------------------------------------------------- # Object Modes (named based on context.mode) -class _defs_edit_armature: +class _defs_edit_armature: @ToolDef.from_fn def roll(): return dict( @@ -682,7 +725,7 @@ class _defs_edit_armature: return dict( idname="builtin.extrude_to_cursor", label="Extrude to Cursor", - cursor='CROSSHAIR', + cursor="CROSSHAIR", icon="ops.armature.extrude_cursor", widget=None, keymap=(), @@ -690,7 +733,6 @@ class _defs_edit_armature: class _defs_edit_mesh: - @ToolDef.from_fn def rip_region(): def draw_settings(_context, layout, tool): @@ -723,6 +765,7 @@ class _defs_edit_mesh: props = tool.operator_properties("mesh.polybuild_face_at_cursor_move") props_macro = props.MESH_OT_polybuild_face_at_cursor layout.prop(props_macro, "create_quads") + return dict( idname="builtin.poly_build", label="Poly Build", @@ -823,9 +866,9 @@ class _defs_edit_mesh: def draw_settings(context, layout, tool, *, extra=False): props = tool.operator_properties("mesh.bevel") - region_is_header = context.region.type == 'TOOL_HEADER' + region_is_header = context.region.type == "TOOL_HEADER" - edge_bevel = props.affect == 'EDGES' + edge_bevel = props.affect == "EDGES" if not extra: if region_is_header: @@ -867,7 +910,7 @@ class _defs_edit_mesh: col.active = edge_bevel col.prop(props, "miter_outer", text="Miter Outer") col.prop(props, "miter_inner", text="Inner") - if props.miter_inner == 'ARC': + if props.miter_inner == "ARC": col.prop(props, "spread") layout.separator() @@ -880,9 +923,11 @@ class _defs_edit_mesh: layout.prop(props, "profile_type") - if props.profile_type == 'CUSTOM': + if props.profile_type == "CUSTOM": tool_settings = context.tool_settings - layout.template_curveprofile(tool_settings, "custom_bevel_profile_preset") + layout.template_curveprofile( + tool_settings, "custom_bevel_profile_preset" + ) return dict( idname="builtin.bevel", @@ -899,9 +944,7 @@ class _defs_edit_mesh: idname="builtin.extrude_region", label="Extrude Region", # The operator description isn't useful in this case, give our own. - description=( - "Extrude freely or along an axis" - ), + description=("Extrude freely or along an axis"), icon="ops.mesh.extrude_region_move", widget="VIEW3D_GGT_xform_extrude", # Important to use same operator as 'E' key. @@ -929,6 +972,7 @@ class _defs_edit_mesh: props = tool.operator_properties("mesh.extrude_region_shrink_fatten") props_macro = props.TRANSFORM_OT_shrink_fatten layout.prop(props_macro, "use_even_offset") + return dict( idname="builtin.extrude_along_normals", label="Extrude Along Normals", @@ -958,7 +1002,7 @@ class _defs_edit_mesh: return dict( idname="builtin.extrude_to_cursor", label="Extrude to Cursor", - cursor='CROSSHAIR', + cursor="CROSSHAIR", icon="ops.mesh.dupli_extrude_cursor", widget=None, keymap=(), @@ -967,7 +1011,6 @@ class _defs_edit_mesh: @ToolDef.from_fn def loopcut_slide(): - def draw_settings(_context, layout, tool): props = tool.operator_properties("mesh.loopcut_slide") props_macro = props.MESH_OT_loopcut @@ -999,6 +1042,7 @@ class _defs_edit_mesh: def draw_settings(_context, layout, tool): props = tool.operator_properties("mesh.vertices_smooth") layout.prop(props, "repeat") + return dict( idname="builtin.smooth", label="Smooth", @@ -1015,6 +1059,7 @@ class _defs_edit_mesh: layout.prop(props, "uniform") layout.prop(props, "normal") layout.prop(props, "seed") + return dict( idname="builtin.randomize", label="Randomize", @@ -1068,7 +1113,7 @@ class _defs_edit_mesh: layout.prop(props, "use_occlude_geometry") layout.prop(props, "only_selected") layout.prop(props, "xray") - region_is_header = bpy.context.region.type == 'TOOL_HEADER' + region_is_header = bpy.context.region.type == "TOOL_HEADER" if region_is_header: show_extra = True else: @@ -1083,15 +1128,16 @@ class _defs_edit_mesh: layout.prop(props, "angle_snapping_increment", text="") if show_extra: layout.popover("TOPBAR_PT_tool_settings_extra", text="...") + return dict( idname="builtin.knife", label="Knife", - cursor='KNIFE', + cursor="KNIFE", icon="ops.mesh.knife_tool", widget=None, keymap=(), draw_settings=draw_settings, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) @ToolDef.from_fn @@ -1102,6 +1148,7 @@ class _defs_edit_mesh: layout.prop(props, "clear_inner") layout.prop(props, "clear_outer") layout.prop(props, "threshold") + return dict( idname="builtin.bisect", label="Bisect", @@ -1113,7 +1160,6 @@ class _defs_edit_mesh: class _defs_edit_curve: - @ToolDef.from_fn def draw(): def draw_settings(context, layout, _tool, *, extra=False): @@ -1122,7 +1168,7 @@ class _defs_edit_curve: cps = tool_settings.curve_paint_settings region_type = context.region.type - if region_type == 'TOOL_HEADER': + if region_type == "TOOL_HEADER": if not extra: layout.prop(cps, "curve_type", text="") layout.prop(cps, "depth_mode", expand=True) @@ -1132,13 +1178,13 @@ class _defs_edit_curve: layout.use_property_split = True layout.use_property_decorate = False - if region_type != 'TOOL_HEADER': + if region_type != "TOOL_HEADER": layout.prop(cps, "curve_type") layout.separator() - if cps.curve_type == 'BEZIER': + if cps.curve_type == "BEZIER": layout.prop(cps, "fit_method") layout.prop(cps, "error_threshold") - if region_type != 'TOOL_HEADER': + if region_type != "TOOL_HEADER": row = layout.row(heading="Detect Corners", align=True) else: row = layout.row(heading="Corners", align=True) @@ -1156,13 +1202,13 @@ class _defs_edit_curve: col.prop(cps, "radius_max", text="Max") col.prop(cps, "use_pressure_radius") - if region_type != 'TOOL_HEADER' or cps.depth_mode == 'SURFACE': + if region_type != "TOOL_HEADER" or cps.depth_mode == "SURFACE": layout.separator() - if region_type != 'TOOL_HEADER': + if region_type != "TOOL_HEADER": row = layout.row() row.prop(cps, "depth_mode", expand=True) - if cps.depth_mode == 'SURFACE': + if cps.depth_mode == "SURFACE": col = layout.column() col.prop(cps, "surface_offset") col.prop(cps, "use_offset_absolute") @@ -1174,7 +1220,7 @@ class _defs_edit_curve: return dict( idname="builtin.draw", label="Draw", - cursor='PAINT_BRUSH', + cursor="PAINT_BRUSH", icon="ops.curve.draw", widget=None, keymap=(), @@ -1197,7 +1243,7 @@ class _defs_edit_curve: return dict( idname="builtin.extrude_cursor", label="Extrude to Cursor", - cursor='CROSSHAIR', + cursor="CROSSHAIR", icon="ops.curve.extrude_cursor", widget=None, keymap=(), @@ -1209,10 +1255,11 @@ class _defs_edit_curve: props = tool.operator_properties("curve.pen") layout.prop(props, "close_spline") layout.prop(props, "extrude_handle") + return dict( idname="builtin.pen", label="Curve Pen", - cursor='CROSSHAIR', + cursor="CROSSHAIR", icon="ops.curve.pen", widget=None, keymap=(), @@ -1234,9 +1281,7 @@ class _defs_edit_curve: return dict( idname="builtin.radius", label="Radius", - description=( - "Expand or contract the radius of the selected curve points" - ), + description=("Expand or contract the radius of the selected curve points"), icon="ops.curve.radius", widget="VIEW3D_GGT_tool_generic_handle_free", keymap=(), @@ -1249,6 +1294,7 @@ class _defs_edit_curve: layout.prop(props, "uniform") layout.prop(props, "normal") layout.prop(props, "seed") + return dict( idname="builtin.randomize", label="Randomize", @@ -1260,7 +1306,6 @@ class _defs_edit_curve: class _defs_pose: - @ToolDef.from_fn def breakdown(): return dict( @@ -1293,7 +1338,6 @@ class _defs_pose: class _defs_particle: - @staticmethod def generate_from_brushes(context): return generate_from_enum_ex( @@ -1306,7 +1350,6 @@ class _defs_particle: class _defs_sculpt: - @staticmethod def generate_from_brushes(context): return generate_from_enum_ex( @@ -1410,6 +1453,7 @@ class _defs_sculpt: layout.prop(props, "trim_mode", expand=False) layout.prop(props, "trim_extrude_mode", expand=False) layout.prop(props, "use_cursor_depth", expand=False) + return dict( idname="builtin.box_trim", label="Box Trim", @@ -1427,6 +1471,7 @@ class _defs_sculpt: layout.prop(props, "trim_orientation", expand=False) layout.prop(props, "trim_extrude_mode", expand=False) layout.prop(props, "use_cursor_depth", expand=False) + return dict( idname="builtin.lasso_trim", label="Lasso Trim", @@ -1460,10 +1505,10 @@ class _defs_sculpt: row = layout.row(align=True) row.prop(props, "deform_axis") layout.prop(props, "orientation", expand=False) - if props.type == 'SURFACE_SMOOTH': + if props.type == "SURFACE_SMOOTH": layout.prop(props, "surface_smooth_shape_preservation", expand=False) layout.prop(props, "surface_smooth_current_vertex", expand=False) - elif props.type == 'SHARPEN': + elif props.type == "SHARPEN": layout.prop(props, "sharpen_smooth_ratio", expand=False) layout.prop(props, "sharpen_intensify_detail_strength", expand=False) layout.prop(props, "sharpen_curvature_smooth_iterations", expand=False) @@ -1505,7 +1550,7 @@ class _defs_sculpt: def draw_settings(_context, layout, tool): props = tool.operator_properties("sculpt.color_filter") layout.prop(props, "type", expand=False) - if props.type == 'FILL': + if props.type == "FILL": layout.prop(props, "fill_color", expand=False) layout.prop(props, "strength") @@ -1554,15 +1599,16 @@ class _defs_sculpt: class _defs_vertex_paint: - @staticmethod def poll_select_mask(context): if context is None: return True ob = context.active_object - return (ob and ob.type == 'MESH' and - (ob.data.use_paint_mask or - ob.data.use_paint_mask_vertex)) + return ( + ob + and ob.type == "MESH" + and (ob.data.use_paint_mask or ob.data.use_paint_mask_vertex) + ) @staticmethod def generate_from_brushes(context): @@ -1576,14 +1622,12 @@ class _defs_vertex_paint: class _defs_texture_paint: - @staticmethod def poll_select_mask(context): if context is None: return True ob = context.active_object - return (ob and ob.type == 'MESH' and - (ob.data.use_paint_mask)) + return ob and ob.type == "MESH" and (ob.data.use_paint_mask) @staticmethod def generate_from_brushes(context): @@ -1593,20 +1637,21 @@ class _defs_texture_paint: icon_prefix="brush.paint_texture.", type=bpy.types.Brush, attr="image_tool", - cursor='PAINT_CROSS', + cursor="PAINT_CROSS", ) class _defs_weight_paint: - @staticmethod def poll_select_mask(context): if context is None: return True ob = context.active_object - return (ob and ob.type == 'MESH' and - (ob.data.use_paint_mask or - ob.data.use_paint_mask_vertex)) + return ( + ob + and ob.type == "MESH" + and (ob.data.use_paint_mask or ob.data.use_paint_mask_vertex) + ) @staticmethod def generate_from_brushes(context): @@ -1628,11 +1673,12 @@ class _defs_weight_paint: else: return layout.label(text="Weight: %.3f" % weight) + return dict( idname="builtin.sample_weight", label="Sample Weight", icon="ops.paint.weight_sample", - cursor='EYEDROPPER', + cursor="EYEDROPPER", widget=None, keymap=(), draw_settings=draw_settings, @@ -1644,7 +1690,7 @@ class _defs_weight_paint: idname="builtin.sample_vertex_group", label="Sample Vertex Group", icon="ops.paint.weight_sample_group", - cursor='EYEDROPPER', + cursor="EYEDROPPER", widget=None, keymap=(), ) @@ -1655,6 +1701,7 @@ class _defs_weight_paint: brush = context.tool_settings.weight_paint.brush if brush is not None: from bl_ui.properties_paint_common import UnifiedPaintPanel + UnifiedPaintPanel.prop_unified( layout, context, @@ -1688,7 +1735,6 @@ class _defs_weight_paint: class _defs_image_generic: - @staticmethod def poll_uvedit(context): if context is None: @@ -1705,9 +1751,7 @@ class _defs_image_generic: return dict( idname="builtin.cursor", label="Cursor", - description=( - "Set the cursor location, drag to transform" - ), + description=("Set the cursor location, drag to transform"), icon="ops.generic.cursor", keymap=(), ) @@ -1719,12 +1763,11 @@ class _defs_image_generic: def draw_settings(_context, layout, tool): props = tool.operator_properties("image.sample") layout.prop(props, "size") + return dict( idname="builtin.sample", label="Sample", - description=( - "Sample pixel values under the cursor" - ), + description=("Sample pixel values under the cursor"), icon="ops.paint.weight_sample", # XXX, needs own icon. keymap="Image Editor Tool: Sample", draw_settings=draw_settings, @@ -1732,7 +1775,6 @@ class _defs_image_generic: class _defs_image_uv_transform: - @ToolDef.from_fn def translate(): return dict( @@ -1771,9 +1813,7 @@ class _defs_image_uv_transform: return dict( idname="builtin.transform", label="Transform", - description=( - "Supports any combination of grab, rotate, and scale at once" - ), + description=("Supports any combination of grab, rotate, and scale at once"), icon="ops.transform.transform", widget="IMAGE_GGT_gizmo2d", # No keymap default action, only for gizmo! @@ -1781,7 +1821,6 @@ class _defs_image_uv_transform: class _defs_image_uv_select: - @ToolDef.from_fn def select(): return dict( @@ -1799,6 +1838,7 @@ class _defs_image_uv_select: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) + return dict( idname="builtin.select_box", label="Select Box", @@ -1815,6 +1855,7 @@ class _defs_image_uv_select: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) + return dict( idname="builtin.select_lasso", label="Select Lasso", @@ -1835,6 +1876,7 @@ class _defs_image_uv_select: def draw_cursor(_context, tool, xy): from gpu_extras.presets import draw_circle_2d + props = tool.operator_properties("uv.select_circle") radius = props.radius draw_circle_2d(xy, (1.0,) * 4, radius, segments=32) @@ -1851,7 +1893,6 @@ class _defs_image_uv_select: class _defs_image_uv_edit: - @ToolDef.from_fn def rip_region(): return dict( @@ -1861,16 +1902,16 @@ class _defs_image_uv_edit: # TODO: generic operator (UV version of `VIEW3D_GGT_tool_generic_handle_free`). widget=None, keymap=(), - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) class _defs_image_uv_sculpt: - @staticmethod def generate_from_brushes(context): def draw_cursor(context, _tool, xy): from gpu_extras.presets import draw_circle_2d + tool_settings = context.tool_settings uv_sculpt = tool_settings.uv_sculpt if not uv_sculpt.show_brush: @@ -1895,13 +1936,12 @@ class _defs_image_uv_sculpt: operator="sculpt.uv_sculpt_stroke", keymap="Image Editor Tool: Uv, Sculpt Stroke", draw_cursor=draw_cursor, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ), ) class _defs_gpencil_paint: - @staticmethod def gpencil_primitive_toolbar(context, layout, _tool, props): paint = context.tool_settings.gpencil_paint @@ -1934,7 +1974,7 @@ class _defs_gpencil_paint: icon_prefix="brush.gpencil_draw.", type=bpy.types.Brush, attr="gpencil_tool", - cursor='DOT', + cursor="DOT", tooldef_keywords=dict( operator="gpencil.draw", ), @@ -1947,11 +1987,12 @@ class _defs_gpencil_paint: row = layout.row() row.use_property_split = False row.prop(props, "flat_caps") + return dict( idname="builtin.cutter", label="Cutter", icon="ops.gpencil.stroke_cutter", - cursor='KNIFE', + cursor="KNIFE", widget=None, keymap=(), draw_settings=draw_settings, @@ -1967,7 +2008,7 @@ class _defs_gpencil_paint: idname="builtin.line", label="Line", icon="ops.gpencil.primitive_line", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap=(), draw_settings=draw_settings, @@ -1983,7 +2024,7 @@ class _defs_gpencil_paint: idname="builtin.polyline", label="Polyline", icon="ops.gpencil.primitive_polyline", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap=(), draw_settings=draw_settings, @@ -1999,7 +2040,7 @@ class _defs_gpencil_paint: idname="builtin.box", label="Box", icon="ops.gpencil.primitive_box", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap=(), draw_settings=draw_settings, @@ -2015,7 +2056,7 @@ class _defs_gpencil_paint: idname="builtin.circle", label="Circle", icon="ops.gpencil.primitive_circle", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap=(), draw_settings=draw_settings, @@ -2031,7 +2072,7 @@ class _defs_gpencil_paint: idname="builtin.arc", label="Arc", icon="ops.gpencil.primitive_arc", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap=(), draw_settings=draw_settings, @@ -2047,7 +2088,7 @@ class _defs_gpencil_paint: idname="builtin.curve", label="Curve", icon="ops.gpencil.primitive_curve", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap=(), draw_settings=draw_settings, @@ -2060,11 +2101,12 @@ class _defs_gpencil_paint: row = layout.row() row.use_property_split = False row.prop(props, "mode", expand=True) + return dict( idname="builtin.eyedropper", label="Eyedropper", icon="ops.paint.eyedropper_add", - cursor='EYEDROPPER', + cursor="EYEDROPPER", widget=None, keymap=(), draw_settings=draw_settings, @@ -2084,7 +2126,7 @@ class _defs_gpencil_paint: idname="builtin.interpolate", label="Interpolate", icon="ops.pose.breakdowner", - cursor='DEFAULT', + cursor="DEFAULT", widget=None, keymap=(), draw_settings=draw_settings, @@ -2094,11 +2136,11 @@ class _defs_gpencil_paint: class _defs_gpencil_edit: def is_segment(context): ts = context.scene.tool_settings - if context.mode == 'EDIT_GPENCIL': - return ts.gpencil_selectmode_edit == 'SEGMENT' - elif context.mode == 'SCULPT_GPENCIL': + if context.mode == "EDIT_GPENCIL": + return ts.gpencil_selectmode_edit == "SEGMENT" + elif context.mode == "SCULPT_GPENCIL": return ts.use_gpencil_select_mask_segment - elif context.mode == 'VERTEX_GPENCIL': + elif context.mode == "VERTEX_GPENCIL": return ts.use_gpencil_vertex_select_mask_segment else: return False @@ -2117,7 +2159,10 @@ class _defs_gpencil_edit: def select(): def draw_settings(context, layout, _tool): if _defs_gpencil_edit.is_segment(context): - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + layout.prop( + context.tool_settings.gpencil_sculpt, "intersection_threshold" + ) + return dict( idname="builtin.select", label="Tweak", @@ -2135,7 +2180,10 @@ class _defs_gpencil_edit: row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) if _defs_gpencil_edit.is_segment(context): - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + layout.prop( + context.tool_settings.gpencil_sculpt, "intersection_threshold" + ) + return dict( idname="builtin.select_box", label="Select Box", @@ -2153,7 +2201,10 @@ class _defs_gpencil_edit: row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) if _defs_gpencil_edit.is_segment(context): - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + layout.prop( + context.tool_settings.gpencil_sculpt, "intersection_threshold" + ) + return dict( idname="builtin.select_lasso", label="Select Lasso", @@ -2172,10 +2223,13 @@ class _defs_gpencil_edit: row.prop(props, "mode", text="", expand=True, icon_only=True) layout.prop(props, "radius") if _defs_gpencil_edit.is_segment(context): - layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold") + layout.prop( + context.tool_settings.gpencil_sculpt, "intersection_threshold" + ) def draw_cursor(_context, tool, xy): from gpu_extras.presets import draw_circle_2d + props = tool.operator_properties("gpencil.select_circle") radius = props.radius draw_circle_2d(xy, (1.0,) * 4, radius, segments=32) @@ -2195,11 +2249,8 @@ class _defs_gpencil_edit: return dict( idname="builtin.radius", label="Radius", - description=( - "Expand or contract the radius of the selected points" - ), + description=("Expand or contract the radius of the selected points"), icon="ops.gpencil.radius", - widget=None, keymap=(), ) @@ -2247,7 +2298,7 @@ class _defs_gpencil_edit: idname="builtin.transform_fill", label="Transform Fill", icon="ops.gpencil.transform_fill", - cursor='DEFAULT', + cursor="DEFAULT", widget=None, keymap=(), draw_settings=draw_settings, @@ -2268,7 +2319,7 @@ class _defs_gpencil_edit: idname="builtin.interpolate", label="Interpolate", icon="ops.pose.breakdowner", - cursor='DEFAULT', + cursor="DEFAULT", widget=None, keymap=(), draw_settings=draw_settings, @@ -2276,16 +2327,21 @@ class _defs_gpencil_edit: class _defs_gpencil_sculpt: - @staticmethod def poll_select_mask(context): if context is None: return True ob = context.active_object ts = context.scene.tool_settings - return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_select_mask_point or - ts.use_gpencil_select_mask_stroke or - ts.use_gpencil_select_mask_segment) + return ( + ob + and ob.type == "GPENCIL" + and ( + ts.use_gpencil_select_mask_point + or ts.use_gpencil_select_mask_stroke + or ts.use_gpencil_select_mask_segment + ) + ) @staticmethod def generate_from_brushes(context): @@ -2302,7 +2358,6 @@ class _defs_gpencil_sculpt: class _defs_gpencil_weight: - @staticmethod def generate_from_brushes(context): return generate_from_enum_ex( @@ -2318,7 +2373,6 @@ class _defs_gpencil_weight: class _defs_curves_sculpt: - @ToolDef.from_fn def selection_paint(): return dict( @@ -2334,7 +2388,7 @@ class _defs_curves_sculpt: idname="builtin_brush.comb", label="Comb", icon="ops.curves.sculpt_comb", - data_block='COMB', + data_block="COMB", ) @ToolDef.from_fn @@ -2343,7 +2397,7 @@ class _defs_curves_sculpt: idname="builtin_brush.add", label="Add", icon="ops.curves.sculpt_add", - data_block='ADD', + data_block="ADD", ) @ToolDef.from_fn @@ -2352,7 +2406,7 @@ class _defs_curves_sculpt: idname="builtin_brush.delete", label="Delete", icon="ops.curves.sculpt_delete", - data_block='DELETE', + data_block="DELETE", ) @ToolDef.from_fn @@ -2361,7 +2415,7 @@ class _defs_curves_sculpt: idname="builtin_brush.snake_hook", label="Snake Hook", icon="ops.curves.sculpt_snake_hook", - data_block='SNAKE_HOOK', + data_block="SNAKE_HOOK", ) @ToolDef.from_fn @@ -2370,7 +2424,7 @@ class _defs_curves_sculpt: idname="builtin_brush.grow_shrink", label="Grow/Shrink", icon="ops.curves.sculpt_grow_shrink", - data_block='GROW_SHRINK', + data_block="GROW_SHRINK", ) @ToolDef.from_fn @@ -2379,7 +2433,7 @@ class _defs_curves_sculpt: idname="builtin_brush.pinch", label="Pinch", icon="ops.curves.sculpt_pinch", - data_block='PINCH', + data_block="PINCH", ) @ToolDef.from_fn @@ -2388,7 +2442,7 @@ class _defs_curves_sculpt: idname="builtin_brush.smooth", label="Smooth", icon="ops.curves.sculpt_smooth", - data_block='SMOOTH', + data_block="SMOOTH", ) @ToolDef.from_fn @@ -2397,7 +2451,7 @@ class _defs_curves_sculpt: idname="builtin_brush.puff", label="Puff", icon="ops.curves.sculpt_puff", - data_block='PUFF', + data_block="PUFF", ) @ToolDef.from_fn @@ -2420,16 +2474,21 @@ class _defs_curves_sculpt: class _defs_gpencil_vertex: - @staticmethod def poll_select_mask(context): if context is None: return True ob = context.active_object ts = context.scene.tool_settings - return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_vertex_select_mask_point or - ts.use_gpencil_vertex_select_mask_stroke or - ts.use_gpencil_vertex_select_mask_segment) + return ( + ob + and ob.type == "GPENCIL" + and ( + ts.use_gpencil_vertex_select_mask_point + or ts.use_gpencil_vertex_select_mask_stroke + or ts.use_gpencil_vertex_select_mask_segment + ) + ) @staticmethod def generate_from_brushes(context): @@ -2439,7 +2498,7 @@ class _defs_gpencil_vertex: icon_prefix="brush.paint_vertex.", type=bpy.types.Brush, attr="gpencil_vertex_tool", - cursor='DOT', + cursor="DOT", tooldef_keywords=dict( operator="gpencil.vertex_paint", ), @@ -2447,7 +2506,6 @@ class _defs_gpencil_vertex: class _defs_node_select: - @ToolDef.from_fn def select(): return dict( @@ -2465,6 +2523,7 @@ class _defs_node_select: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) + return dict( idname="builtin.select_box", label="Select Box", @@ -2481,6 +2540,7 @@ class _defs_node_select: row = layout.row() row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) + return dict( idname="builtin.select_lasso", label="Select Lasso", @@ -2501,6 +2561,7 @@ class _defs_node_select: def draw_cursor(_context, tool, xy): from gpu_extras.presets import draw_circle_2d + props = tool.operator_properties("node.select_circle") radius = props.radius draw_circle_2d(xy, (1.0,) * 4, radius, segments=32) @@ -2517,7 +2578,6 @@ class _defs_node_select: class _defs_node_edit: - @ToolDef.from_fn def links_cut(): return dict( @@ -2526,20 +2586,17 @@ class _defs_node_edit: icon="ops.node.links_cut", widget=None, keymap="Node Tool: Links Cut", - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) class _defs_sequencer_generic: - @ToolDef.from_fn def cursor(): return dict( idname="builtin.cursor", label="Cursor", - description=( - "Set the cursor location, drag to transform" - ), + description=("Set the cursor location, drag to transform"), icon="ops.generic.cursor", keymap="Sequencer Tool: Cursor", ) @@ -2551,15 +2608,16 @@ class _defs_sequencer_generic: row = layout.row() row.use_property_split = False row.prop(props, "type", expand=True) + return dict( idname="builtin.blade", label="Blade", icon="ops.sequencer.blade", - cursor='CROSSHAIR', + cursor="CROSSHAIR", widget=None, keymap="Sequencer Tool: Blade", draw_settings=draw_settings, - options={'KEYMAP_FALLBACK'}, + options={"KEYMAP_FALLBACK"}, ) @ToolDef.from_fn @@ -2567,9 +2625,7 @@ class _defs_sequencer_generic: return dict( idname="builtin.sample", label="Sample", - description=( - "Sample pixel values under the cursor" - ), + description=("Sample pixel values under the cursor"), icon="ops.paint.weight_sample", # XXX, needs own icon. keymap="Sequencer Tool: Sample", ) @@ -2612,9 +2668,7 @@ class _defs_sequencer_generic: return dict( idname="builtin.transform", label="Transform", - description=( - "Supports any combination of grab, rotate, and scale at once" - ), + description=("Supports any combination of grab, rotate, and scale at once"), icon="ops.transform.transform", widget="SEQUENCER_GGT_gizmo2d", # No keymap default action, only for gizmo! @@ -2640,6 +2694,7 @@ class _defs_sequencer_select: row.use_property_split = False row.prop(props, "mode", text="", expand=True, icon_only=True) pass + return dict( idname="builtin.select_box", label="Select Box", @@ -2651,10 +2706,10 @@ class _defs_sequencer_select: class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): - bl_space_type = 'IMAGE_EDITOR' - bl_region_type = 'TOOLS' + bl_space_type = "IMAGE_EDITOR" + bl_region_type = "TOOLS" bl_label = "Tools" # not visible - bl_options = {'HIDE_HEADER'} + bl_options = {"HIDE_HEADER"} # Satisfy the 'ToolSelectPanelHelper' API. keymap_prefix = "Image Editor Tool:" @@ -2666,7 +2721,7 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): def tools_from_context(cls, context, mode=None): if mode is None: if context.space_data is None: - mode = 'VIEW' + mode = "VIEW" else: mode = context.space_data.mode for tools in (cls._tools[None], cls._tools.get(mode, ())): @@ -2714,11 +2769,11 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): None: [ # for all modes ], - 'VIEW': [ + "VIEW": [ _defs_image_generic.sample, *_tools_annotate, ], - 'UV': [ + "UV": [ *_tools_select, _defs_image_generic.cursor, None, @@ -2734,10 +2789,10 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): else () ), ], - 'MASK': [ + "MASK": [ None, ], - 'PAINT': [ + "PAINT": [ _defs_texture_paint.generate_from_brushes, None, *_tools_annotate, @@ -2746,10 +2801,10 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): class NODE_PT_tools_active(ToolSelectPanelHelper, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'TOOLS' + bl_space_type = "NODE_EDITOR" + bl_region_type = "TOOLS" bl_label = "Tools" # not visible - bl_options = {'HIDE_HEADER'} + bl_options = {"HIDE_HEADER"} # Satisfy the 'ToolSelectPanelHelper' API. keymap_prefix = "Node Editor Tool:" @@ -2810,10 +2865,10 @@ class NODE_PT_tools_active(ToolSelectPanelHelper, Panel): class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" bl_label = "Tools" # not visible - bl_options = {'HIDE_HEADER'} + bl_options = {"HIDE_HEADER"} # Satisfy the 'ToolSelectPanelHelper' API. keymap_prefix = "3D View Tool:" @@ -2902,12 +2957,12 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): # _defs_view3d_generic.cursor, # End group. ], - 'OBJECT': [ + "OBJECT": [ *_tools_default, None, _tools_view3d_add, ], - 'POSE': [ + "POSE": [ *_tools_default, None, ( @@ -2916,7 +2971,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_pose.relax, ), ], - 'EDIT_ARMATURE': [ + "EDIT_ARMATURE": [ *_tools_default, None, _defs_edit_armature.roll, @@ -2931,9 +2986,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ), _defs_transform.shear, ], - 'EDIT_MESH': [ + "EDIT_MESH": [ *_tools_default, - None, _tools_view3d_add, None, @@ -2980,7 +3034,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_edit_mesh.rip_edge, ), ], - 'EDIT_CURVE': [ + "EDIT_CURVE": [ *_tools_default, None, _defs_edit_curve.draw, @@ -2996,34 +3050,37 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_transform.shear, _defs_edit_curve.curve_vertex_randomize, ], - 'EDIT_SURFACE': [ + "EDIT_CURVES": [ + *_tools_select, + ], + "EDIT_SURFACE": [ *_tools_default, None, _defs_transform.shear, ], - 'EDIT_METABALL': [ + "EDIT_METABALL": [ *_tools_default, None, _defs_transform.shear, ], - 'EDIT_LATTICE': [ + "EDIT_LATTICE": [ *_tools_default, None, _defs_transform.shear, ], - 'EDIT_TEXT': [ + "EDIT_TEXT": [ _defs_view3d_generic.cursor, None, *_tools_annotate, _defs_view3d_generic.ruler, ], - 'PARTICLE': [ + "PARTICLE": [ *_tools_select, _defs_view3d_generic.cursor, None, _defs_particle.generate_from_brushes, ], - 'SCULPT': [ + "SCULPT": [ _defs_sculpt.generate_from_brushes, None, ( @@ -3056,7 +3113,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_annotate, ], - 'PAINT_TEXTURE': [ + "PAINT_TEXTURE": [ _defs_texture_paint.generate_from_brushes, None, lambda context: ( @@ -3066,7 +3123,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ), *_tools_annotate, ], - 'PAINT_VERTEX': [ + "PAINT_VERTEX": [ _defs_vertex_paint.generate_from_brushes, None, lambda context: ( @@ -3076,7 +3133,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ), *_tools_annotate, ], - 'PAINT_WEIGHT': [ + "PAINT_WEIGHT": [ _defs_weight_paint.generate_from_brushes, _defs_weight_paint.gradient, None, @@ -3102,7 +3159,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ), *_tools_annotate, ], - 'PAINT_GPENCIL': [ + "PAINT_GPENCIL": [ _defs_view3d_generic.cursor, None, _defs_gpencil_paint.generate_from_brushes, @@ -3121,7 +3178,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_annotate, ], - 'EDIT_GPENCIL': [ + "EDIT_GPENCIL": [ *_tools_gpencil_select, _defs_view3d_generic.cursor, None, @@ -3140,7 +3197,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_annotate, ], - 'SCULPT_GPENCIL': [ + "SCULPT_GPENCIL": [ _defs_gpencil_sculpt.generate_from_brushes, None, *_tools_annotate, @@ -3150,12 +3207,12 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): else () ), ], - 'WEIGHT_GPENCIL': [ + "WEIGHT_GPENCIL": [ _defs_gpencil_weight.generate_from_brushes, None, *_tools_annotate, ], - 'VERTEX_GPENCIL': [ + "VERTEX_GPENCIL": [ _defs_gpencil_vertex.generate_from_brushes, None, *_tools_annotate, @@ -3166,7 +3223,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): else () ), ], - 'SCULPT_CURVES': [ + "SCULPT_CURVES": [ _defs_curves_sculpt.selection_paint, None, _defs_curves_sculpt.add, @@ -3187,10 +3244,10 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): - bl_space_type = 'SEQUENCE_EDITOR' - bl_region_type = 'TOOLS' + bl_space_type = "SEQUENCE_EDITOR" + bl_region_type = "TOOLS" bl_label = "Tools" # not visible - bl_options = {'HIDE_HEADER'} + bl_options = {"HIDE_HEADER"} # Satisfy the 'ToolSelectPanelHelper' API. keymap_prefix = "Sequence Editor Tool:" @@ -3235,9 +3292,8 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): # The keys match sequence editors view type: `context.space_data.view_type`. # The values represent the tools, see `ToolSelectPanelHelper` for details. _tools = { - None: [ - ], - 'PREVIEW': [ + None: [], + "PREVIEW": [ *_tools_select, _defs_sequencer_generic.cursor, None, @@ -3249,11 +3305,11 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_sequencer_generic.sample, *_tools_annotate, ], - 'SEQUENCER': [ + "SEQUENCER": [ *_tools_select, _defs_sequencer_generic.blade, ], - 'SEQUENCER_PREVIEW': [ + "SEQUENCER_PREVIEW": [ *_tools_select, None, *_tools_annotate, @@ -3272,5 +3328,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 50bb1e42602..1872b3cbd51 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -326,7 +326,7 @@ class TOPBAR_MT_file_new(Menu): # Expand template paths. # Use a set to avoid duplicate user/system templates. - # This is a corner case, but users managed to do it! T76849. + # This is a corner case, but users managed to do it! #76849. app_templates = set() for path in template_paths: for d in os.listdir(path): diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 421e600c58f..96b83be6ad8 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -2319,13 +2319,21 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel): bl_label = "New Features" def draw(self, context): - self._draw_items( - context, ( - ({"property": "use_sculpt_tools_tilt"}, ("blender/blender/issues/82877", "#82877")), - ({"property": "use_extended_asset_browser"}, ("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")), - ({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")), - ), - ) + self._draw_items(context, + (({"property": "use_sculpt_tools_tilt"}, + ("blender/blender/issues/82877", + "#82877")), + ({"property": "use_extended_asset_browser"}, + ("blender/blender/projects/10", + "Pipeline, Assets & IO Project Page")), + ({"property": "use_override_templates"}, + ("blender/blender/issues/73318", + "Milestone 4")), + ({"property": "use_new_volume_nodes"}, + ("blender/blender/issues/103248", + "#103248")), + ), + ) class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 1ce457480e5..97eb45462ed 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -161,6 +161,8 @@ class VIEW3D_HT_tool_header(Header): sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True) sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True) + layout.prop(context.object.data, "use_sculpt_collision", icon='MOD_PHYSICS', icon_only=True, toggle=True) + # Expand panels from the side-bar as popovers. popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"} @@ -890,7 +892,7 @@ class VIEW3D_HT_header(Header): row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'}) # While exposing `shading.show_xray(_wireframe)` is correct. - # this hides the key shortcut from users: T70433. + # this hides the key shortcut from users: #70433. if has_pose_mode: draw_depressed = overlay.show_xray_bone elif shading.type == 'WIREFRAME': @@ -2052,6 +2054,7 @@ class VIEW3D_MT_select_edit_curves(Menu): layout.operator("curves.select_all", text="Invert").action = 'INVERT' layout.operator("curves.select_random", text="Random") layout.operator("curves.select_end", text="Endpoints") + layout.operator("curves.select_linked", text="Linked") class VIEW3D_MT_select_sculpt_curves(Menu): @@ -2267,7 +2270,7 @@ class VIEW3D_MT_add(Menu): # NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context. # NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents - # "align_view" to work on first call (see T32719). + # "align_view" to work on first call (see #32719). layout.operator_context = 'EXEC_REGION_WIN' # layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH') @@ -5375,7 +5378,7 @@ class VIEW3D_MT_shading_ex_pie(Menu): pie.prop_enum(view.shading, "type", value='WIREFRAME') pie.prop_enum(view.shading, "type", value='SOLID') - # Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: T58661. + # Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: #58661. if context.pose_object: pie.prop(view.overlay, "show_xray_bone", icon='XRAY') else: @@ -6706,13 +6709,12 @@ class VIEW3D_PT_overlay_sculpt(Panel): def poll(cls, context): return ( context.mode == 'SCULPT' and - (context.sculpt_object and context.tool_settings.sculpt) + context.sculpt_object ) def draw(self, context): layout = self.layout tool_settings = context.tool_settings - sculpt = tool_settings.sculpt view = context.space_data overlay = view.overlay diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index 37032657d7a..6fc0b643552 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -639,7 +639,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo): # Note that this controls order of options in `insert keyframe` menu. # Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut. -# See also T51867. +# See also #51867. classes = ( BUILTIN_KSI_Available, BUILTIN_KSI_Location, diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 2856e33931b..3deec135888 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -76,21 +76,11 @@ def node_group_items(context): yield NodeItemCustom(draw=lambda self, layout, context: layout.separator()) - def contains_group(nodetree, group): - if nodetree == group: - return True - else: - for node in nodetree.nodes: - if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None: - if contains_group(node.node_tree, group): - return True - return False - for group in context.blend_data.node_groups: if group.bl_idname != ntree.bl_idname: continue # filter out recursive groups - if contains_group(group, ntree): + if group.contains_tree(ntree): continue # filter out hidden nodetrees if group.name.startswith('.'): diff --git a/source/blender/asset_system/AS_asset_representation.hh b/source/blender/asset_system/AS_asset_representation.hh index 65f7e08f395..6793cd8097c 100644 --- a/source/blender/asset_system/AS_asset_representation.hh +++ b/source/blender/asset_system/AS_asset_representation.hh @@ -23,11 +23,15 @@ struct ID; namespace blender::asset_system { +class AssetLibrary; + class AssetRepresentation { AssetIdentifier identifier_; /** Indicate if this is a local or external asset, and as such, which of the union members below * should be used. */ const bool is_local_id_ = false; + /** Asset library that owns this asset representation. */ + const AssetLibrary *owner_asset_library_; struct ExternalAsset { std::string name; @@ -44,10 +48,13 @@ class AssetRepresentation { /** Constructs an asset representation for an external ID. The asset will not be editable. */ AssetRepresentation(AssetIdentifier &&identifier, StringRef name, - std::unique_ptr metadata); + std::unique_ptr metadata, + const AssetLibrary &owner_asset_library); /** Constructs an asset representation for an ID stored in the current file. This makes the asset * local and fully editable. */ - AssetRepresentation(AssetIdentifier &&identifier, ID &id); + AssetRepresentation(AssetIdentifier &&identifier, + ID &id, + const AssetLibrary &owner_asset_library); AssetRepresentation(AssetRepresentation &&other); /* Non-copyable type. */ AssetRepresentation(const AssetRepresentation &other) = delete; @@ -65,6 +72,7 @@ class AssetRepresentation { AssetMetaData &get_metadata() const; /** Returns if this asset is stored inside this current file, and as such fully editable. */ bool is_local_id() const; + const AssetLibrary &owner_asset_library() const; }; } // namespace blender::asset_system diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index 2379e738e37..fdb54c16af6 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -169,13 +169,14 @@ AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_p std::unique_ptr metadata) { AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path); - return asset_storage_->add_external_asset(std::move(identifier), name, std::move(metadata)); + return asset_storage_->add_external_asset( + std::move(identifier), name, std::move(metadata), *this); } AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id) { AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path); - return asset_storage_->add_local_id_asset(std::move(identifier), id); + return asset_storage_->add_local_id_asset(std::move(identifier), id, *this); } bool AssetLibrary::remove_asset(AssetRepresentation &asset) diff --git a/source/blender/asset_system/intern/asset_representation.cc b/source/blender/asset_system/intern/asset_representation.cc index 573358b7df7..13c6236a6dd 100644 --- a/source/blender/asset_system/intern/asset_representation.cc +++ b/source/blender/asset_system/intern/asset_representation.cc @@ -17,15 +17,24 @@ namespace blender::asset_system { AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, StringRef name, - std::unique_ptr metadata) - : identifier_(identifier), is_local_id_(false), external_asset_() + std::unique_ptr metadata, + const AssetLibrary &owner_asset_library) + : identifier_(identifier), + is_local_id_(false), + owner_asset_library_(&owner_asset_library), + external_asset_() { external_asset_.name = name; external_asset_.metadata_ = std::move(metadata); } -AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, ID &id) - : identifier_(identifier), is_local_id_(true), local_asset_id_(&id) +AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, + ID &id, + const AssetLibrary &owner_asset_library) + : identifier_(identifier), + is_local_id_(true), + owner_asset_library_(&owner_asset_library), + local_asset_id_(&id) { if (!id.asset_data) { throw std::invalid_argument("Passed ID is not an asset"); @@ -75,6 +84,11 @@ bool AssetRepresentation::is_local_id() const return is_local_id_; } +const AssetLibrary &AssetRepresentation::owner_asset_library() const +{ + return *owner_asset_library_; +} + } // namespace blender::asset_system using namespace blender; diff --git a/source/blender/asset_system/intern/asset_storage.cc b/source/blender/asset_system/intern/asset_storage.cc index 73b9d582616..f14b0cd0f79 100644 --- a/source/blender/asset_system/intern/asset_storage.cc +++ b/source/blender/asset_system/intern/asset_storage.cc @@ -15,18 +15,21 @@ namespace blender::asset_system { -AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, ID &id) +AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, + ID &id, + const AssetLibrary &owner_asset_library) { return *local_id_assets_.lookup_key_or_add( - std::make_unique(std::move(identifier), id)); + std::make_unique(std::move(identifier), id, owner_asset_library)); } AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier, StringRef name, - std::unique_ptr metadata) + std::unique_ptr metadata, + const AssetLibrary &owner_asset_library) { - return *external_assets_.lookup_key_or_add( - std::make_unique(std::move(identifier), name, std::move(metadata))); + return *external_assets_.lookup_key_or_add(std::make_unique( + std::move(identifier), name, std::move(metadata), owner_asset_library)); } bool AssetStorage::remove_asset(AssetRepresentation &asset) diff --git a/source/blender/asset_system/intern/asset_storage.hh b/source/blender/asset_system/intern/asset_storage.hh index 2b4614abca5..c4a9ec14319 100644 --- a/source/blender/asset_system/intern/asset_storage.hh +++ b/source/blender/asset_system/intern/asset_storage.hh @@ -35,9 +35,12 @@ class AssetStorage { /** See #AssetLibrary::add_external_asset(). */ AssetRepresentation &add_external_asset(AssetIdentifier &&identifier, StringRef name, - std::unique_ptr metadata); + std::unique_ptr metadata, + const AssetLibrary &owner_asset_library); /** See #AssetLibrary::add_external_asset(). */ - AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, ID &id); + AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, + ID &id, + const AssetLibrary &owner_asset_library); /** See #AssetLibrary::remove_asset(). */ bool remove_asset(AssetRepresentation &asset); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index d4f5be617fd..a8cbb89c7ad 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -165,7 +165,7 @@ int BLF_load_unique(const char *name) /* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from * our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same - * (T101506). Enable again later with change of font, placement, or rendering - Harley. */ + * (#101506). Enable again later with change of font, placement, or rendering - Harley. */ if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) { font->face_flags &= ~FT_FACE_FLAG_KERNING; } diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index cc4be9f7f0e..8601c61bdac 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -40,7 +40,7 @@ typedef int32_t ft_pix; /* Macros copied from `include/freetype/internal/ftobjs.h`. */ /** - * FIXME(@campbellbarton): Follow rounding from Blender 3.1x and older. + * FIXME(@ideasman42): Follow rounding from Blender 3.1x and older. * This is what users will expect and changing this creates wider spaced text. * Use this macro to communicate that rounding should be used, using floor is to avoid * user visible changes, which can be reviewed and handled separately. diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 79d0fe6e20a..8c875ec456d 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -271,7 +271,7 @@ struct bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob) * In this case the active-selected is an obvious choice when finding the target for a * constraint for eg. however from the users perspective the active pose bone of the * active object is the _real_ active bone, so any other non-active selected bone - * is a candidate for being the other selected bone, see: T58447. + * is a candidate for being the other selected bone, see: #58447. */ struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob); /** diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 46aacf1e7fd..e0ffea9aadf 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -37,7 +37,7 @@ struct bActionGroup; /* Container for data required to do FCurve and Driver evaluation. */ typedef struct AnimationEvalContext { /* For drivers, so that they have access to the dependency graph and the current view layer. See - * T77086. */ + * #77086. */ struct Depsgraph *depsgraph; /* FCurves and Drivers can be evaluated at a different time than the current scene time, for diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index f5514fcc632..395a0c34538 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,7 +25,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 8 +#define BLENDER_FILE_SUBVERSION 9 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 388d45211bf..0a391575598 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -2,17 +2,12 @@ #pragma once -#include "BKE_curves.h" - /** \file * \ingroup bke * \brief Low-level operations for curves. */ -#include - #include "BLI_bounds_types.hh" -#include "BLI_cache_mutex.hh" #include "BLI_generic_virtual_array.hh" #include "BLI_index_mask.hh" #include "BLI_math_matrix_types.hh" @@ -20,12 +15,12 @@ #include "BLI_offset_indices.hh" #include "BLI_shared_cache.hh" #include "BLI_span.hh" -#include "BLI_task.hh" #include "BLI_vector.hh" #include "BLI_virtual_array.hh" #include "BKE_attribute.hh" #include "BKE_attribute_math.hh" +#include "BKE_curves.h" namespace blender::bke { diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index cdade9209b6..62b80a627bb 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -63,7 +63,7 @@ typedef struct FModifierTypeInfo { /** #eFMI_Action_Types. */ short acttype; /** #eFMI_Requirement_Flags. */ - short requires; + short requires_flag; /** name of modifier in interface. */ char name[64]; /** name of struct for SDNA. */ diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 7c3a64f1cad..daf394b811a 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -134,7 +134,7 @@ typedef struct Main { /** * When linking, disallow creation of new data-blocks. - * Make sure we don't do this by accident, see T76738. + * Make sure we don't do this by accident, see #76738. */ bool is_locked_for_linking; @@ -425,7 +425,7 @@ int set_listbasepointers(struct Main *main, struct ListBase *lb[]); /** * The size of thumbnails (optionally) stored in the `.blend` files header. * - * NOTE(@campbellbarton): This is kept small as it's stored uncompressed in the `.blend` file, + * NOTE(@ideasman42): This is kept small as it's stored uncompressed in the `.blend` file, * where a larger size would increase the size of every `.blend` file unreasonably. * If we wanted to increase the size, we'd want to use compression (JPEG or similar). */ diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index c9928b9c4d6..be447ab0ecc 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -229,11 +229,6 @@ void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigne void BKE_mesh_smooth_flag_set(struct Mesh *me, bool use_smooth); void BKE_mesh_auto_smooth_flag_set(struct Mesh *me, bool use_auto_smooth, float auto_smooth_angle); -/** - * Needed after converting a mesh with subsurf optimal display to mesh. - */ -void BKE_mesh_edges_set_draw_render(struct Mesh *me); - /** * Used for unit testing; compares two meshes, checking only * differences we care about. should be usable with leaf's @@ -817,7 +812,7 @@ struct Mesh *BKE_mesh_merge_verts(struct Mesh *mesh, * Account for custom-data such as UVs becoming detached because of imprecision * in custom-data interpolation. * Without running this operation subdivision surface can cause UVs to be disconnected, - * see: T81065. + * see: #81065. */ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index 087716706e1..5be751c4a47 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -145,10 +145,7 @@ void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh); */ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh); -/** - * Convert legacy #MFace.edcode to edge #ME_EDGEDRAW. - */ -void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old); +void BKE_mesh_calc_edges_legacy(struct Mesh *me); void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh); diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index 46f62220d91..40d3b95139c 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -170,7 +170,6 @@ void BKE_mesh_vert_edge_vert_map_create( */ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, int **r_mem, - const struct MEdge *medge, int totedge, const struct MPoly *mpoly, int totpoly, @@ -183,7 +182,6 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, */ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int **r_mem, - const struct MEdge *medge, int totedge, const struct MPoly *mpoly, int totpoly, @@ -317,8 +315,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], * starting at 1 (0 being used as 'invalid' flag). * Note it's callers's responsibility to MEM_freeN returned array. */ -int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge, - int totedge, +int *BKE_mesh_calc_smoothgroups(int totedge, const struct MPoly *mpoly, int totpoly, const struct MLoop *mloop, @@ -353,6 +350,7 @@ Array> build_vert_to_edge_map(Span edges, int verts_num); Array> build_vert_to_poly_map(Span polys, Span loops, int verts_num); Array> build_vert_to_loop_map(Span loops, int verts_num); Array> build_edge_to_loop_map(Span loops, int edges_num); +Array> build_edge_to_poly_map(Span polys, Span loops, int edges_num); Vector> build_edge_to_loop_map_resizable(Span loops, int edges_num); inline int poly_loop_prev(const MPoly &poly, int loop_i) diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index c9992a5e3d7..b9c62f39c57 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -132,7 +132,7 @@ struct MeshRuntime { * * Modifiers that edit the mesh data in-place must set this to false * (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh - * data will be used for drawing, missing changes from modifiers. See T79517. + * data will be used for drawing, missing changes from modifiers. See #79517. */ bool is_original_bmesh = false; @@ -174,6 +174,13 @@ struct MeshRuntime { */ BitVector<> subsurf_face_dot_tags; + /** + * A bit vector the size of the number of edges, set to true for edges that should be drawn in + * the viewport. Created by the "Optimal Display" feature of the subdivision surface modifier. + * Otherwise it will be empty. + */ + BitVector<> subsurf_optimal_display_edges; + MeshRuntime() = default; ~MeshRuntime(); diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 086f21aa897..0fa3d16d328 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -36,10 +36,10 @@ struct PropertyRNA; /* Data Management */ /** - * Remove the given NLA strip from the NLA track it occupies, free the strip's data, - * and the strip itself. + * Frees the given NLA strip, and calls #BKE_nlastrip_remove_and_free to + * remove and free all children strips. */ -void BKE_nlastrip_free(ListBase *strips, struct NlaStrip *strip, bool do_id_user); +void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user); /** * Remove the given NLA track from the set of NLA tracks, free the track's data, * and the track itself. @@ -94,10 +94,22 @@ void BKE_nla_tracks_copy_from_adt(struct Main *bmain, struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt, struct NlaTrack *prev, bool is_liboverride); + /** * Create a NLA Strip referencing the given Action. */ struct NlaStrip *BKE_nlastrip_new(struct bAction *act); + +/* + * Removes the given NLA strip from the list of strips provided. + */ +void BKE_nlastrip_remove(ListBase *strips, struct NlaStrip *strip); + +/* + * Removes the given NLA strip from the list of strips provided, and frees it's memory. + */ +void BKE_nlastrip_remove_and_free(ListBase *strips, struct NlaStrip *strip, const bool do_id_user); + /** * Add new NLA-strip to the top of the NLA stack - i.e. * into the last track if space, or a new one otherwise. @@ -139,13 +151,9 @@ void BKE_nlastrips_sort_strips(ListBase *strips); void BKE_nlastrips_add_strip_unsafe(ListBase *strips, struct NlaStrip *strip); /** - * \brief NULL checks incoming strip and verifies no overlap / invalid - * configuration against other strips in NLA Track. - * - * \param strips: - * \param strip: - * \return true - * \return false + * NULL checks incoming strip and verifies no overlap / invalid + * configuration against other strips in NLA Track before calling + * #BKE_nlastrips_add_strip_unsafe. */ bool BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip); @@ -215,11 +223,16 @@ bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end); void BKE_nlatrack_sort_strips(struct NlaTrack *nlt); /** - * Add the given NLA-Strip to the given NLA-Track, assuming that it - * isn't currently attached to another one. + * Add the given NLA-Strip to the given NLA-Track. + * Calls #BKE_nlastrips_add_strip to check if strip can be added. */ bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip, bool is_liboverride); +/** + * Remove the NLA-Strip from the given NLA-Track. + */ +void BKE_nlatrack_remove_strip(struct NlaTrack *track, struct NlaStrip *strip); + /** * Get the extents of the given NLA-Track including gaps between strips, * returning whether this succeeded or not diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index c358f56c0d9..a0f6405a6ac 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -504,7 +504,13 @@ struct bNodeTree *ntreeFromID(struct ID *id); void ntreeFreeLocalNode(struct bNodeTree *ntree, struct bNode *node); void ntreeFreeLocalTree(struct bNodeTree *ntree); struct bNode *ntreeFindType(struct bNodeTree *ntree, int type); -bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup); + +/** + * Check recursively if a node tree contains another. + */ +bool ntreeContainsTree(const struct bNodeTree *tree_to_search_in, + const struct bNodeTree *tree_to_search_for); + void ntreeUpdateAllNew(struct Main *main); void ntreeUpdateAllUsers(struct Main *main, struct ID *id); @@ -989,7 +995,7 @@ void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwid void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size); /** * \warning Nodes defining a storage type _must_ allocate this for new nodes. - * Otherwise nodes will reload as undefined (T46619). + * Otherwise nodes will reload as undefined (#46619). */ void node_type_storage(struct bNodeType *ntype, const char *storagename, @@ -1534,6 +1540,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define GEO_NODE_BLUR_ATTRIBUTE 1190 #define GEO_NODE_IMAGE 1191 #define GEO_NODE_INTERPOLATE_CURVES 1192 +#define GEO_NODE_EDGES_TO_FACE_GROUPS 1193 /** \} */ diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index c77faf98b25..92ea5bd4986 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -370,7 +370,7 @@ void BKE_object_dimensions_get(struct Object *ob, float r_vec[3]); * typically this caused by parenting, constraints or delta-scale. * * Re-using these values from the object causes a feedback loop - * when multiple values are modified at once in some situations. see: T69536. + * when multiple values are modified at once in some situations. see: #69536. */ void BKE_object_dimensions_set_ex(struct Object *ob, const float value[3], diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 367dc9a3035..12a55151c9b 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -775,7 +775,7 @@ void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node, /** * \note doing a full search on all vertices here seems expensive, * however this is important to avoid having to recalculate bound-box & sync the buffers to the - * GPU (which is far more expensive!) See: T47232. + * GPU (which is far more expensive!) See: #47232. */ bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node); diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index b13a1cbd034..448a8938bd3 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -120,7 +120,7 @@ void shrinkwrapGpencilModifier_deform(struct ShrinkwrapGpencilModifierData *mmd, int numVerts); /** - * Used in `editmesh_mask_extract.c` to shrink-wrap the extracted mesh to the sculpt. + * Used in `editmesh_mask_extract.cc` to shrink-wrap the extracted mesh to the sculpt. */ void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C, struct Object *ob_source, diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index d65df26da77..dd01c4ffd07 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -32,8 +32,13 @@ typedef struct SubsurfRuntimeData { SubdivSettings settings; /* Cached subdivision surface descriptor, with topology and settings. */ - struct Subdiv *subdiv; - bool set_by_draw_code; + struct Subdiv *subdiv_cpu; + struct Subdiv *subdiv_gpu; + + /* Recent usage markers for UI diagnostics. To avoid UI flicker due to races + * between evaluation and UI redraw, they are set to 2 when an evaluator is used, + * and count down every frame. */ + char used_cpu, used_gpu; /* Cached mesh wrapper data, to be used for GPU subdiv or lazy evaluation on CPU. */ bool has_gpu_subdiv; diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index bd0fdadec5c..459db322b01 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -911,7 +911,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, /* set the Mesh to only copy needed data */ CustomData_MeshMasks mask = md_datamask->mask; - /* needMapping check here fixes bug T28112, otherwise it's + /* needMapping check here fixes bug #28112, otherwise it's * possible that it won't be copied */ CustomData_MeshMasks_update(&mask, &append_mask); if (need_mapping) { @@ -1467,7 +1467,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, /* Add orco coordinates to final and deformed mesh if requested. */ if (final_datamask.vmask & CD_MASK_ORCO) { - /* FIXME(@campbellbarton): avoid the need to convert to mesh data just to add an orco layer. */ + /* FIXME(@ideasman42): avoid the need to convert to mesh data just to add an orco layer. */ BKE_mesh_wrapper_ensure_mdata(mesh_final); add_orco_mesh(ob, em_input, mesh_final, mesh_orco, CD_ORCO); @@ -1678,7 +1678,7 @@ void makeDerivedMesh(struct Depsgraph *depsgraph, BLI_assert(ob->type == OB_MESH); /* Evaluated meshes aren't supposed to be created on original instances. If you do, - * they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */ + * they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */ BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE); BKE_object_free_derived_caches(ob); @@ -1715,7 +1715,7 @@ Mesh *mesh_get_eval_final(struct Depsgraph *depsgraph, BLI_assert(DEG_is_evaluating(depsgraph) == false); /* Evaluated meshes aren't supposed to be created on original instances. If you do, - * they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */ + * they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */ BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE); /* if there's no evaluated mesh or the last data mask used doesn't include @@ -1757,7 +1757,7 @@ Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph, BLI_assert(DEG_is_evaluating(depsgraph) == false); /* Evaluated meshes aren't supposed to be created on original instances. If you do, - * they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */ + * they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */ BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE); /* if there's no derived mesh or the last data mask used doesn't include diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index d4a7a7cbb1e..8549f2df1dc 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1406,7 +1406,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ * - no "selected only", since this is often used in the backend * - no "minimum length" (we will apply this later), otherwise * single-keyframe curves will increase the overall length by - * a phantom frame (T50354) + * a phantom frame (#50354) */ BKE_fcurve_calc_range(fcu, &nmin, &nmax, false, false); diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c index 9b68c19c6e2..e84e0874484 100644 --- a/source/blender/blenkernel/intern/anim_data.c +++ b/source/blender/blenkernel/intern/anim_data.c @@ -1461,7 +1461,7 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, AnimData *adt) /* relink active track/strip - even though strictly speaking this should only be used * if we're in 'tweaking mode', we need to be able to have this loaded back for - * undo, but also since users may not exit tweak-mode before saving (T24535). + * undo, but also since users may not exit tweak-mode before saving (#24535). */ /* TODO: it's not really nice that anyone should be able to save the file in this * state, but it's going to be too hard to enforce this single case. */ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 928626ecc7b..09120a34d80 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -2880,7 +2880,7 @@ static void nlastrip_evaluate_meta(const int evaluation_mode, STRIP_EVAL_NOBLEND)); /* directly evaluate child strip into accumulation buffer... - * - there's no need to use a temporary buffer (as it causes issues [T40082]) + * - there's no need to use a temporary buffer (as it causes issues [#40082]) */ if (tmp_nes) { nlastrip_evaluate(evaluation_mode, @@ -4163,7 +4163,7 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context); ok = BKE_animsys_write_to_rna_path(&anim_rna, curval); - /* Flush results & status codes to original data for UI (T59984) */ + /* Flush results & status codes to original data for UI (#59984) */ if (ok && DEG_is_active(depsgraph)) { animsys_write_orig_anim_rna(&id_ptr, fcu->rna_path, fcu->array_index, curval); diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index b3990b2b7fc..c35639830aa 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -884,7 +884,7 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name) void BKE_appdir_program_path_init(const char *argv0) { #ifdef WITH_PYTHON_MODULE - /* NOTE(@campbellbarton): Always use `argv[0]` as is, when building as a Python module. + /* NOTE(@ideasman42): Always use `argv[0]` as is, when building as a Python module. * Otherwise other methods of detecting the binary that override this argument * which must point to the Python module for data-files to be detected. */ STRNCPY(g_app.program_filepath, argv0); diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 5f749472b2d..6c809a8269d 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -925,7 +925,7 @@ static void pose_channel_flush_to_orig_if_needed(struct Depsgraph *depsgraph, return; } bPoseChannel *pchan_orig = pchan->orig_pchan; - /* TODO(sergey): Using BKE_pose_copy_pchan_result() introduces T70901, but why? */ + /* TODO(sergey): Using BKE_pose_copy_pchan_result() introduces #70901, but why? */ copy_m4_m4(pchan_orig->pose_mat, pchan->pose_mat); copy_m4_m4(pchan_orig->chan_mat, pchan->chan_mat); copy_v3_v3(pchan_orig->pose_head, pchan->pose_mat[3]); diff --git a/source/blender/blenkernel/intern/blendfile.cc b/source/blender/blenkernel/intern/blendfile.cc index 4deaa6d2109..8f0e462cd27 100644 --- a/source/blender/blenkernel/intern/blendfile.cc +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -203,7 +203,7 @@ static void setup_app_data(bContext *C, * But if they close one of the screens, * undo will ensure that the scene being operated on will be activated * (otherwise we'd be undoing on an off-screen scene which isn't acceptable). - * see: T43424 + * see: #43424 */ wmWindow *win; bScreen *curscreen = nullptr; diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index 49b480fcb64..8b97ab4b061 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -613,10 +613,10 @@ static void loose_data_instantiate_collection_process( } /* Forced instantiation of indirectly appended collections is not wanted. Users can now - * easily instantiate collections (and their objects) as needed by themselves. See T67032. */ + * easily instantiate collections (and their objects) as needed by themselves. See #67032. */ /* We need to check that objects in that collections are already instantiated in a scene. * Otherwise, it's better to add the collection to the scene's active collection, than to - * instantiate its objects in active scene's collection directly. See T61141. + * instantiate its objects in active scene's collection directly. See #61141. * * NOTE: We only check object directly into that collection, not recursively into its * children. @@ -625,7 +625,7 @@ static void loose_data_instantiate_collection_process( /* The collection could be linked/appended together with an Empty object instantiating it, * better not instantiate the collection in the view-layer in that case. * - * Can easily happen when copy/pasting such instantiating empty, see T93839. */ + * Can easily happen when copy/pasting such instantiating empty, see #93839. */ const bool collection_is_instantiated = collection_instantiated_by_any_object(bmain, collection); /* Always consider adding collections directly selected by the user. */ @@ -751,7 +751,7 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i * While this is not ideal (in theory no object should remain un-owned), in case of indirectly * linked objects, the other solution would be to add them to a local collection, which would * make them directly linked. Think for now keeping them indirectly linked is more important. - * Ref. T93757. + * Ref. #93757. */ if (is_linking && (item->tag & LINK_APPEND_TAG_INDIRECT) != 0) { continue; @@ -935,7 +935,7 @@ static int foreach_libblock_link_append_callback(LibraryIDLinkCallbackData *cb_d * the dependency here. Indeed, either they are both linked in another way (through their own * meshes for shape keys e.g.), or this is an unsupported case (two shape-keys depending on * each-other need to be also 'linked' in by their respective meshes, independent shape-keys - * are not allowed). ref T96048. */ + * are not allowed). ref #96048. */ if (id != cb_data->id_self && BKE_idtype_idcode_is_linkable(GS(cb_data->id_self->name))) { BKE_library_foreach_ID_link( cb_data->bmain, id, foreach_libblock_link_append_callback, data, IDWALK_NOP); @@ -1244,7 +1244,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re mainl = BLO_library_link_begin(&blo_handle, libname, lapp_context->params); lib = mainl->curlib; BLI_assert(lib != NULL); - /* In case lib was already existing but not found originally, see T99820. */ + /* In case lib was already existing but not found originally, see #99820. */ lib->id.tag &= ~LIB_TAG_MISSING; if (mainl->versionfile < 250) { @@ -1424,7 +1424,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context, /* All override rules need to be up to date, since there will be no do_version here, otherwise * older, now-invalid rules might be applied and likely fail, or some changes might be missing, - * etc. See T93353. */ + * etc. See #93353. */ BKE_lib_override_library_main_operations_create(bmain, true, NULL); /* Remove all IDs to be reloaded from Main. */ diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index a8482f905d1..8d5737e940d 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -1598,7 +1598,7 @@ struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mo void BKE_brush_debug_print_state(Brush *br) { /* create a fake brush and set it to the defaults */ - Brush def = {{nullptr}}; + Brush def = blender::dna::shallow_zero_initialize(); brush_defaults(&def); #define BR_TEST(field, t) \ diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 2d5dc9010bf..47f031e8dca 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -537,7 +537,7 @@ void BKE_camera_view_frame_ex(const Scene *scene, r_vec[3][2] = depth; if (do_clip) { - /* Ensure the frame isn't behind the near clipping plane, T62814. */ + /* Ensure the frame isn't behind the near clipping plane, #62814. */ float fac = ((camera->clip_start + 0.1f) / -r_vec[0][2]) * scale[2]; for (uint i = 0; i < 4; i++) { if (camera->type == CAM_ORTHO) { diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c index 5145f1cbbc0..99236ed81ea 100644 --- a/source/blender/blenkernel/intern/colorband.c +++ b/source/blender/blenkernel/intern/colorband.c @@ -144,7 +144,7 @@ static float color_sample_remove_cost(const struct ColorResampleElem *c) return area; } -/* TODO(@campbellbarton): create `BLI_math_filter` ? */ +/* TODO(@ideasman42): create `BLI_math_filter` ? */ static float filter_gauss(float x) { const float gaussfac = 1.6f; @@ -469,7 +469,7 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4]) } else { /* was setting to 0.0 in 2.56 & previous, but this - * is incorrect for the last element, see T26732. */ + * is incorrect for the last element, see #26732. */ fac = (a != coba->tot) ? 0.0f : 1.0f; } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index fa9a18859b8..1ffae922408 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -141,7 +141,7 @@ bConstraintOb *BKE_constraints_make_evalob( /* NOTE: Versions <= 2.76 assumed that "default" order * would always get used, so we may seem some rig * breakage as a result. However, this change here - * is needed to fix T46599 + * is needed to fix #46599 */ cob->rotOrder = ob->rotmode; } @@ -1222,7 +1222,7 @@ static void vectomat(const float vec[3], } /* NOTE: even though 'n' is normalized, don't use 'project_v3_v3v3_normalized' below - * because precision issues cause a problem in near degenerate states, see: T53455. */ + * because precision issues cause a problem in near degenerate states, see: #53455. */ /* project the up vector onto the plane specified by n */ project_v3_v3v3(proj, u, n); /* first u onto n... */ @@ -1558,7 +1558,7 @@ static void followpath_evaluate(bConstraint *con, bConstraintOb *cob, ListBase * /* un-apply scaling caused by path */ if ((data->followflag & FOLLOWPATH_RADIUS) == 0) { - /* XXX(@campbellbarton): Assume that scale correction means that radius + /* XXX(@ideasman42): Assume that scale correction means that radius * will have some scale error in it. */ float obsize[3]; @@ -1953,7 +1953,7 @@ static void rotlike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar /* To allow compatible rotations, must get both rotations in the order of the owner... */ mat4_to_eulO(obeul, rot_order, cob->matrix); /* We must get compatible eulers from the beginning because - * some of them can be modified below (see bug T21875). + * some of them can be modified below (see bug #21875). * Additionally, since this constraint is based on euler rotation math, it doesn't work well * with shear. The Y axis is chosen as the main axis when we orthogonalize the matrix because * constraints are used most commonly on bones. */ @@ -3835,7 +3835,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar unit_m4(targetMatrix); INIT_MINMAX(curveMin, curveMax); - /* XXX(@campbellbarton): don't think this is good calling this here because + /* XXX(@ideasman42): don't think this is good calling this here because * the other object's data is lazily initializing bounding-box information. * This could cause issues when evaluating from a thread. * If the depsgraph ensures the bound-box is always available, a code-path could @@ -4024,7 +4024,7 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t mat4_to_size(dvec, ct->matrix); if (is_negative_m4(ct->matrix)) { - /* Bugfix T27886: (this is a limitation that riggers will have to live with for now). + /* Bugfix #27886: (this is a limitation that riggers will have to live with for now). * We can't be sure which axis/axes are negative, * though we know that something is negative. * Assume we don't care about negativity of separate axes. */ @@ -4307,7 +4307,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph), /* Transform normal into requested space */ /* Note that in this specific case, we need to keep scaling in non-parented 'local2world' * object case, because SpaceTransform also takes it into account when handling normals. - * See T42447. */ + * See #42447. */ unit_m4(mat); BKE_constraint_mat_convertspace( cob->ob, cob->pchan, cob, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true); @@ -5605,7 +5605,7 @@ bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool { const short type = con->type; if (BKE_constraint_remove(list, con)) { - /* ITASC needs to be rebuilt once a constraint is removed T26920. */ + /* ITASC needs to be rebuilt once a constraint is removed #26920. */ if (clear_dep && ELEM(type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK)) { BIK_clear_data(ob->pose); } @@ -5831,7 +5831,7 @@ static bConstraint *add_new_constraint(Object *ob, } case CONSTRAINT_TYPE_ACTION: { /* The Before or Split modes require computing in local space, but - * for objects the Local space doesn't make sense (T78462, D6095 etc). + * for objects the Local space doesn't make sense (#78462, D6095 etc). * So only default to Before (Split) if the constraint is on a bone. */ if (pchan) { bActionConstraint *data = con->data; @@ -6422,7 +6422,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph, /* Interpolate the enforcement, to blend result of constraint into final owner transform * - all this happens in world-space to prevent any weirdness creeping in - * (T26014 and T25725), since some constraints may not convert the solution back to the input + * (#26014 and #25725), since some constraints may not convert the solution back to the input * space before blending but all are guaranteed to end up in good "world-space" result. */ /* NOTE: all kind of stuff here before (caused trouble), much easier to just interpolate, diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index 906d4c82623..d56aeeb7940 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -398,7 +398,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, } else { /* More complex handling will continue in BKE_crazyspace_build_sculpt. - * Exiting the loop on a non-deform modifier causes issues - T71213. */ + * Exiting the loop on a non-deform modifier causes issues - #71213. */ BLI_assert(crazyspace_modifier_supports_deform(md)); break; } diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 61dc8a22077..6a85e268bca 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -2097,10 +2097,10 @@ static void bevel_list_calc_bisect(BevList *bl) } /* In the unlikely situation that handles define a zeroed direction, - * calculate it from the adjacent points, see T80742. + * calculate it from the adjacent points, see #80742. * * Only do this as a fallback since we typically want the end-point directions - * to be exactly aligned with the handles at the end-point, see T83117. */ + * to be exactly aligned with the handles at the end-point, see #83117. */ if (is_cyclic == false) { bevp0 = &bl->bevpoints[0]; bevp1 = &bl->bevpoints[1]; @@ -2251,8 +2251,8 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) int nr; float q[4]; const bool is_cyclic = bl->poly != -1; - /* NOTE(@campbellbarton): For non-cyclic curves only initialize the first direction - * (via `vec_to_quat`), necessary for symmetry, see T71137. + /* NOTE(@ideasman42): For non-cyclic curves only initialize the first direction + * (via `vec_to_quat`), necessary for symmetry, see #71137. * Otherwise initialize the first and second points before propagating rotation forward. * This is historical as changing this can cause significantly different output. * Specifically: `deform_modifiers` test: (`CurveMeshDeform`). @@ -2480,7 +2480,7 @@ static void make_bevel_list_segment_2D(BevList *bl) static void make_bevel_list_2D(BevList *bl) { - /* NOTE(@campbellbarton): `bevp->dir` and `bevp->quat` are not needed for beveling but are + /* NOTE(@ideasman42): `bevp->dir` and `bevp->quat` are not needed for beveling but are * used when making a path from a 2D curve, therefore they need to be set. */ BevPoint *bevp0, *bevp1, *bevp2; @@ -2906,7 +2906,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_ continue; } - /* Scale the threshold so high resolution shapes don't get over reduced, see: T49850. */ + /* Scale the threshold so high resolution shapes don't get over reduced, see: #49850. */ const float threshold_resolu = 0.00001f / resolu; const bool is_cyclic = bl->poly != -1; nr = bl->nr; @@ -3284,7 +3284,7 @@ static void calchandleNurb_intern(BezTriple *bezt, } if (skip_align || - /* When one handle is free, aligning makes no sense, see: T35952 */ + /* When one handle is free, aligning makes no sense, see: #35952 */ ELEM(HD_FREE, bezt->h1, bezt->h2) || /* Also when no handles are aligned, skip this step. */ (!ELEM(HD_ALIGN, bezt->h1, bezt->h2) && !ELEM(HD_ALIGN_DOUBLESIDE, bezt->h1, bezt->h2))) { diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc index 460c96196ea..0e7fb094dd1 100644 --- a/source/blender/blenkernel/intern/curve_bezier.cc +++ b/source/blender/blenkernel/intern/curve_bezier.cc @@ -6,6 +6,8 @@ #include +#include "BLI_task.hh" + #include "BKE_attribute_math.hh" #include "BKE_curves.hh" diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index 28f213ff68c..2a259af1324 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -4,6 +4,8 @@ * \ingroup bke */ +#include "BLI_task.hh" + #include "BKE_attribute_math.hh" #include "BKE_curves.hh" diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index d3c57e5257d..ccecfadb474 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -62,7 +62,6 @@ static void fill_mesh_topology(const int vert_offset, MEdge &edge = edges[profile_edge_offset + i_ring]; edge.v1 = ring_vert_offset + i_profile; edge.v2 = next_ring_vert_offset + i_profile; - edge.flag = ME_EDGEDRAW; } } @@ -78,7 +77,6 @@ static void fill_mesh_topology(const int vert_offset, MEdge &edge = edges[ring_edge_offset + i_profile]; edge.v1 = ring_vert_offset + i_profile; edge.v2 = ring_vert_offset + i_next_profile; - edge.flag = ME_EDGEDRAW; } } @@ -122,7 +120,7 @@ static void fill_mesh_topology(const int vert_offset, } } - const bool has_caps = fill_caps && !main_cyclic && profile_cyclic; + const bool has_caps = fill_caps && !main_cyclic && profile_cyclic && profile_point_num > 2; if (has_caps) { const int poly_num = main_segment_num * profile_segment_num; const int cap_loop_offset = loop_offset + poly_num * 4; @@ -273,7 +271,7 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool const int profile_point_num = profile_offsets.size(i_profile); const int profile_segment_num = curves::segments_num(profile_point_num, profile_cyclic); - const bool has_caps = fill_caps && !main_cyclic && profile_cyclic; + const bool has_caps = fill_caps && !main_cyclic && profile_cyclic && profile_point_num > 2; const int tube_face_num = main_segment_num * profile_segment_num; vert_offset += main_point_num * profile_point_num; diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index b71a705eecb..50b3a1668d2 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -147,7 +147,7 @@ struct LayerTypeInfo { * \note in some cases \a dest pointer is in \a sources * so all functions have to take this into account and delay * applying changes while reading from sources. - * See bug T32395 - Campbell. + * See bug #32395 - Campbell. */ cd_interp interp; @@ -2289,26 +2289,12 @@ bool CustomData_merge(const CustomData *source, return changed; } -static bool attribute_stored_in_bmesh_flag(const StringRef name) -{ - return ELEM(name, - "position", - ".hide_vert", - ".hide_edge", - ".hide_poly", - ".select_vert", - ".select_edge", - ".select_poly", - "material_index", - "sharp_edge"); -} - CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src, const eCustomDataMask mask) { Vector dst_layers; for (const CustomDataLayer &layer : Span{src->layers, src->totlayer}) { - if (attribute_stored_in_bmesh_flag(layer.name)) { + if (BM_attribute_stored_in_bmesh_builtin(layer.name)) { continue; } if (!(mask & CD_TYPE_AS_MASK(layer.type))) { @@ -4370,7 +4356,7 @@ bool CustomData_verify_versions(CustomData *data, const int index) } /* This is a preemptive fix for cases that should not happen * (layers that should not be written in .blend files), - * but can happen due to bugs (see e.g. T62318). + * but can happen due to bugs (see e.g. #62318). * Also for forward compatibility, in future, * we may put into `.blend` file some currently un-written data types, * this should cover that case as well. @@ -4411,9 +4397,9 @@ static bool CustomData_layer_ensure_data_exists(CustomDataLayer *layer, size_t c switch (layer->type) { /* When more instances of corrupt files are found, add them here. */ - case CD_PROP_BOOL: /* See T84935. */ - case CD_MLOOPUV: /* See T90620. */ - case CD_PROP_FLOAT2: /* See T90620. */ + case CD_PROP_BOOL: /* See #84935. */ + case CD_MLOOPUV: /* See #90620. */ + case CD_PROP_FLOAT2: /* See #90620. */ layer->data = MEM_calloc_arrayN(count, typeInfo->size, layerType_getName(layer->type)); BLI_assert(layer->data); if (typeInfo->set_default_value) { @@ -5164,7 +5150,7 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int { BLO_read_data_address(reader, &data->layers); - /* Annoying workaround for bug T31079 loading legacy files with + /* Annoying workaround for bug #31079 loading legacy files with * no polygons _but_ have stale custom-data. */ if (UNLIKELY(count == 0 && data->layers == nullptr && data->totlayer != 0)) { CustomData_reset(data); @@ -5187,8 +5173,8 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int BLO_read_data_address(reader, &layer->data); if (CustomData_layer_ensure_data_exists(layer, count)) { /* Under normal operations, this shouldn't happen, but... - * For a CD_PROP_BOOL example, see T84935. - * For a CD_MLOOPUV example, see T90620. */ + * For a CD_PROP_BOOL example, see #84935. + * For a CD_MLOOPUV example, see #90620. */ CLOG_WARN(&LOG, "Allocated custom data layer that was not saved correctly for layer->type = %d.", layer->type); diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index 745db5e7fe5..49a2861afae 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -1353,7 +1353,7 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, * but it doesn't seem to work in this case. * * Since the plan is to replace this legacy curve object with the curves data-block - * (see T95355), this somewhat hacky inefficient solution is relatively temporary. + * (see #95355), this somewhat hacky inefficient solution is relatively temporary. */ Curve &cow_curve = *reinterpret_cast( BKE_id_copy_ex(nullptr, &original_curve.id, nullptr, LIB_ID_COPY_LOCALIZE)); diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 3c8b76380ee..6f03efe8137 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -683,7 +683,7 @@ bool get_effector_data(EffectorCache *eff, bool ret = false; /* In case surface object is in Edit mode when loading the .blend, - * surface modifier is never executed and bvhtree never built, see T48415. */ + * surface modifier is never executed and bvhtree never built, see #48415. */ if (eff->pd && eff->pd->shape == PFIELD_SHAPE_SURFACE && eff->surmd && eff->surmd->runtime.bvhtree) { /* closest point in the object surface is an effector */ @@ -772,7 +772,7 @@ bool get_effector_data(EffectorCache *eff, if (eff->pd->forcefield == PFIELD_VORTEX || eff->pd->shape == PFIELD_SHAPE_LINE) { add_v3_v3v3(efd->loc, ob->object_to_world[3], translate); } - else { /* normally efd->loc is closest point on effector xy-plane */ + else { /* Normally `efd->loc` is closest point on effector XY-plane. */ sub_v3_v3v3(efd->loc, point->loc, translate); } } @@ -1122,34 +1122,34 @@ void BKE_effectors_apply(ListBase *effectors, float *wind_force, float *impulse) { - /* WARNING(@campbellbarton): historic comment? + /* WARNING(@ideasman42): historic comment? * Many of these parameters don't exist! * - * scene = scene where it runs in, for time and stuff. - * lb = listbase with objects that take part in effecting. - * opco = global coord, as input. - * force = accumulator for force. - * wind_force = accumulator for force only acting perpendicular to a surface. - * speed = actual current speed which can be altered. - * cur_time = "external" time in frames, is constant for static particles. - * loc_time = "local" time in frames, range <0-1> for the lifetime of particle. - * par_layer = layer the caller is in. - * flags = only used for soft-body wind now. - * guide = old speed of particle. + * `scene` = scene where it runs in, for time and stuff. + * `lb` = listbase with objects that take part in effecting. + * `opco` = global coord, as input. + * `force` = accumulator for force. + * `wind_force` = accumulator for force only acting perpendicular to a surface. + * `speed` = actual current speed which can be altered. + * `cur_time` = "external" time in frames, is constant for static particles. + * `loc_time` = "local" time in frames, range <0-1> for the lifetime of particle. + * `par_layer` = layer the caller is in. + * `flags` = only used for soft-body wind now. + * `guide` = old speed of particle. */ /* * Modifies the force on a particle according to its * relation with the effector object * Different kind of effectors include: - * Force-fields: Gravity-like attractor - * (force power is related to the inverse of distance to the power of a falloff value) - * Vortex fields: swirling effectors - * (particles rotate around Z-axis of the object. otherwise, same relation as) - * (Force-fields, but this is not done through a force/acceleration) - * Guide: particles on a path - * (particles are guided along a curve bezier or old nurbs) - * (is independent of other effectors) + * - Force-fields: Gravity-like attractor + * (force power is related to the inverse of distance to the power of a falloff value) + * - Vortex fields: swirling effectors + * (particles rotate around Z-axis of the object. otherwise, same relation as) + * (Force-fields, but this is not done through a force/acceleration) + * - Guide: particles on a path + * (particles are guided along a curve bezier or old nurbs) + * (is independent of other effectors) */ EffectorCache *eff; EffectorData efd; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index d2550f9db0d..304ac5c63a0 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1903,10 +1903,10 @@ static float fcurve_eval_keyframes_interpolate(const FCurve *fcu, * * The threshold here has the following constraints: * - 0.001 is too coarse: - * We get artifacts with 2cm driver movements at 1BU = 1m (see T40332). + * We get artifacts with 2cm driver movements at 1BU = 1m (see #40332). * * - 0.00001 is too fine: - * Weird errors, like selecting the wrong keyframe range (see T39207), occur. + * Weird errors, like selecting the wrong keyframe range (see #39207), occur. * This lower bound was established in b888a32eee8147b028464336ad2404d8155c64dd. */ a = BKE_fcurve_bezt_binarysearch_index_ex(bezts, evaltime, fcu->totvert, 0.0001, &exact); @@ -1914,7 +1914,7 @@ static float fcurve_eval_keyframes_interpolate(const FCurve *fcu, if (exact) { /* Index returned must be interpreted differently when it sits on top of an existing keyframe - * - That keyframe is the start of the segment we need (see action_bug_2.blend in T39207). + * - That keyframe is the start of the segment we need (see action_bug_2.blend in #39207). */ return bezt->vec[1][1]; } @@ -1925,7 +1925,7 @@ static float fcurve_eval_keyframes_interpolate(const FCurve *fcu, const BezTriple *prevbezt = (a > 0) ? (bezt - 1) : bezt; /* Use if the key is directly on the frame, in rare cases this is needed else we get 0.0 instead. - * XXX: consult T39207 for examples of files where failure of these checks can cause issues. */ + * XXX: consult #39207 for examples of files where failure of these checks can cause issues. */ if (fabsf(bezt->vec[1][0] - evaltime) < eps) { return bezt->vec[1][1]; } @@ -1976,7 +1976,7 @@ static float fcurve_eval_keyframes_interpolate(const FCurve *fcu, if (fabsf(v1[1] - v4[1]) < FLT_EPSILON && fabsf(v2[1] - v3[1]) < FLT_EPSILON && fabsf(v3[1] - v4[1]) < FLT_EPSILON) { /* Optimization: If all the handles are flat/at the same values, - * the value is simply the shared value (see T40372 -> F91346). + * the value is simply the shared value (see #40372 -> F91346). */ return v1[1]; } @@ -2285,7 +2285,7 @@ float evaluate_fcurve_driver(PathResolvedRNA *anim_rna, * XXX: additive is a bit more dicey; it really depends then if things are in range or not... */ LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) { - /* If there are range-restrictions, we must definitely block T36950. */ + /* If there are range-restrictions, we must definitely block #36950. */ if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 || (fcm->sfra <= evaltime && fcm->efra >= evaltime)) { /* Within range: here it probably doesn't matter, @@ -2507,7 +2507,7 @@ void BKE_fcurve_blend_read_data(BlendDataReader *reader, ListBase *fcurves) /* group */ BLO_read_data_address(reader, &fcu->grp); - /* clear disabled flag - allows disabled drivers to be tried again (T32155), + /* clear disabled flag - allows disabled drivers to be tried again (#32155), * but also means that another method for "reviving disabled F-Curves" exists */ fcu->flag &= ~FCURVE_DISABLED; @@ -2523,7 +2523,7 @@ void BKE_fcurve_blend_read_data(BlendDataReader *reader, ListBase *fcurves) driver->expr_simple = NULL; /* Give the driver a fresh chance - the operating environment may be different now - * (addons, etc. may be different) so the driver namespace may be sane now T32155. */ + * (addons, etc. may be different) so the driver namespace may be sane now #32155. */ driver->flag &= ~DRIVER_FLAG_INVALID; /* relink variables, targets and their paths */ diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c index 3d1439b5530..5b4a6736004 100644 --- a/source/blender/blenkernel/intern/fcurve_driver.c +++ b/source/blender/blenkernel/intern/fcurve_driver.c @@ -472,8 +472,8 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) /* Check if object or bone, and get transform matrix accordingly: * - "use_eulers" code is used to prevent the problems associated with non-uniqueness - * of euler decomposition from matrices T20870. - * - "local-space" is for T21384, where parent results are not wanted + * of euler decomposition from matrices #20870. + * - "local-space" is for #21384, where parent results are not wanted * but #DTAR_FLAG_LOCAL_CONSTS is for all the common "corrective-shapes-for-limbs" situations. */ if (pchan) { diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc index 285c6a0af4d..66c4477ebc2 100644 --- a/source/blender/blenkernel/intern/fcurve_test.cc +++ b/source/blender/blenkernel/intern/fcurve_test.cc @@ -34,7 +34,7 @@ TEST(evaluate_fcurve, OnKeys) EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f), 13.0f, EPSILON); /* hits 'between' function */ EXPECT_NEAR(evaluate_fcurve(fcu, 3.0f), 19.0f, EPSILON); /* hits 'on or after last' function */ - /* Also test within a specific time epsilon of the keys, as this was an issue in T39207. + /* Also test within a specific time epsilon of the keys, as this was an issue in #39207. * This epsilon is just slightly smaller than the epsilon given to * BKE_fcurve_bezt_binarysearch_index_ex() in fcurve_eval_between_keyframes(), so it should hit * the "exact" code path. */ diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 70a5c90269b..769fc63f2bb 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -215,7 +215,7 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds, # if 0 /* Note (sebbas): * Disabling this "skip section" as not copying borders results in weird cut-off effects. - * It is possible that this cutting off is the reason for line effects as seen in T74559. + * It is possible that this cutting off is the reason for line effects as seen in #74559. * Since domain borders will be handled on the simulation side anyways, * copying border values should not be an issue. */ @@ -3812,7 +3812,7 @@ static void fluid_modifier_processDomain(FluidModifierData *fmd, /* When reading data from cache (has_config == true) ensure that active fields are allocated. * update_flowsflags() and update_obstacleflags() will not find flow sources hidden from renders. - * See also: T72192. */ + * See also: #72192. */ if (has_config) { ensure_flowsfields(fds); ensure_obstaclefields(fds); @@ -4169,7 +4169,7 @@ Mesh *BKE_fluid_modifier_do( * This does not seem particularly useful, but it's backwards compatible. * * Smoke simulation needs a texture space relative to the adaptive domain bounds, not the - * original mesh. So recompute it at this point in the modifier stack. See T58492. */ + * original mesh. So recompute it at this point in the modifier stack. See #58492. */ BKE_mesh_texspace_calc(result); return result; diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 46828a43818..ae9b0f5e558 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -64,7 +64,7 @@ static FModifierTypeInfo FMI_MODNAME = { /*type*/ FMODIFIER_TYPE_MODNAME, /*size*/ sizeof(FMod_ModName), /*acttype*/ FMI_TYPE_SOME_ACTION, - /*requires*/ FMI_REQUIRES_SOME_REQUIREMENT, + /*requires_flag*/ FMI_REQUIRES_SOME_REQUIREMENT, /*name*/ "Modifier Name", /*structName*/ "FMod_ModName", /*storage_size*/ 0, @@ -228,7 +228,7 @@ static FModifierTypeInfo FMI_GENERATOR = { /*type*/ FMODIFIER_TYPE_GENERATOR, /*size*/ sizeof(FMod_Generator), /*acttype*/ FMI_TYPE_GENERATE_CURVE, - /*requires*/ FMI_REQUIRES_NOTHING, + /*requires_flag*/ FMI_REQUIRES_NOTHING, /*name*/ N_("Generator"), /*structName*/ "FMod_Generator", /*storage_size*/ 0, @@ -358,7 +358,7 @@ static FModifierTypeInfo FMI_FN_GENERATOR = { /*type*/ FMODIFIER_TYPE_FN_GENERATOR, /*size*/ sizeof(FMod_FunctionGenerator), /*acttype*/ FMI_TYPE_GENERATE_CURVE, - /*requires*/ FMI_REQUIRES_NOTHING, + /*requires_flag*/ FMI_REQUIRES_NOTHING, /*name*/ N_("Built-In Function"), /*structName*/ "FMod_FunctionGenerator", /*storage_size*/ 0, @@ -471,7 +471,7 @@ static FModifierTypeInfo FMI_ENVELOPE = { /*type*/ FMODIFIER_TYPE_ENVELOPE, /*size*/ sizeof(FMod_Envelope), /*acttype*/ FMI_TYPE_REPLACE_VALUES, - /*requires*/ 0, + /*requires_flag*/ 0, /*name*/ N_("Envelope"), /*structName*/ "FMod_Envelope", /*storage_size*/ 0, @@ -770,7 +770,7 @@ static FModifierTypeInfo FMI_CYCLES = { /*type*/ FMODIFIER_TYPE_CYCLES, /*size*/ sizeof(FMod_Cycles), /*acttype*/ FMI_TYPE_EXTRAPOLATION, - /*requires*/ FMI_REQUIRES_ORIGINAL_DATA, + /*requires_flag*/ FMI_REQUIRES_ORIGINAL_DATA, /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_ACTION, "Cycles"), /*structName*/ "FMod_Cycles", /*storage_size*/ sizeof(tFCMED_Cycles), @@ -832,7 +832,7 @@ static FModifierTypeInfo FMI_NOISE = { /*type*/ FMODIFIER_TYPE_NOISE, /*size*/ sizeof(FMod_Noise), /*acttype*/ FMI_TYPE_REPLACE_VALUES, - /*requires*/ 0, + /*requires_flag*/ 0, /*name*/ N_("Noise"), /*structName*/ "FMod_Noise", /*storage_size*/ 0, @@ -890,7 +890,7 @@ static FModifierTypeInfo FMI_PYTHON = { /*type*/ FMODIFIER_TYPE_PYTHON, /*size*/ sizeof(FMod_Python), /*acttype*/ FMI_TYPE_GENERATE_CURVE, - /*requires*/ FMI_REQUIRES_RUNTIME_CHECK, + /*requires_flag*/ FMI_REQUIRES_RUNTIME_CHECK, /*name*/ N_("Python"), /*structName*/ "FMod_Python", /*storage_size*/ 0, @@ -945,7 +945,7 @@ static FModifierTypeInfo FMI_LIMITS = { /*type*/ FMODIFIER_TYPE_LIMITS, /*size*/ sizeof(FMod_Limits), /*acttype*/ FMI_TYPE_GENERATE_CURVE, - /*requires*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */ + /*requires_flag*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */ /*name*/ N_("Limits"), /*structName*/ "FMod_Limits", /*storage_size*/ 0, @@ -1005,7 +1005,7 @@ static FModifierTypeInfo FMI_STEPPED = { /*type*/ FMODIFIER_TYPE_STEPPED, /*size*/ sizeof(FMod_Limits), /*acttype*/ FMI_TYPE_GENERATE_CURVE, - /*requires*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */ + /*requires_flag*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */ /*name*/ N_("Stepped"), /*structName*/ "FMod_Stepped", /*storage_size*/ 0, diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 6405ce06a5b..67b52f67cfc 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1261,7 +1261,9 @@ bGPDframe *BKE_gpencil_layer_frame_get(bGPDlayer *gpl, int cframe, eGP_GetFrame_ found = true; break; } - if ((gpf->next) && (gpf->next->framenum > cframe)) { + /* If this is the last frame or the next frame is at a later time, we found the right + * frame. */ + if (!(gpf->next) || (gpf->next->framenum > cframe)) { found = true; break; } diff --git a/source/blender/blenkernel/intern/icons_rasterize.c b/source/blender/blenkernel/intern/icons_rasterize.c index 56854c1318e..ea19d3527c3 100644 --- a/source/blender/blenkernel/intern/icons_rasterize.c +++ b/source/blender/blenkernel/intern/icons_rasterize.c @@ -74,7 +74,7 @@ ImBuf *BKE_icon_geom_rasterize(const struct Icon_Geom *geom, const uint size_x, const uchar(*pos)[2] = geom->coords; const uint *col = (void *)geom->colors; - /* TODO(@campbellbarton): Currently rasterizes to fixed size, then scales. + /* TODO(@ideasman42): Currently rasterizes to fixed size, then scales. * Should rasterize to double size for eg instead. */ const int rect_size[2] = {max_ii(256, (int)size_x * 2), max_ii(256, (int)size_y * 2)}; diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 156ad97c923..2921ae59b23 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -797,7 +797,7 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed) if (create_if_needed) { id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty"); id->properties->type = IDP_GROUP; - /* NOTE(@campbellbarton): Don't overwrite the data's name and type + /* NOTE(@ideasman42): Don't overwrite the data's name and type * some functions might need this if they * don't have a real ID, should be named elsewhere. */ // strcpy(id->name, "top_level_group"); diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 5e8a2cad99e..7d25e524928 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -313,7 +313,7 @@ static void image_foreach_path(ID *id, BPathForeachPathData *bpath_data) if (result) { if (flag & BKE_BPATH_FOREACH_PATH_RELOAD_EDITED) { if (!BKE_image_has_packedfile(ima) && - /* Image may have been painted onto (and not saved, T44543). */ + /* Image may have been painted onto (and not saved, #44543). */ !BKE_image_is_dirty(ima)) { BKE_image_signal(bpath_data->bmain, ima, nullptr, IMA_SIGNAL_RELOAD); } diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 7d835c2464d..7a9ef93734b 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1875,7 +1875,7 @@ KeyBlock *BKE_keyblock_add_ctime(Key *key, const char *name, const bool do_force /* In case of absolute keys, there is no point in adding more than one key with the same pos. * Hence only set new key-block pos to current time if none previous one already use it. * Now at least people just adding absolute keys without touching to ctime - * won't have to systematically use retiming func (and have ordering issues, too). See T39897. + * won't have to systematically use retiming func (and have ordering issues, too). See #39897. */ if (!do_force && (key->type != KEY_RELATIVE)) { KeyBlock *it_kb; diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 9e452662055..ee6290027ad 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -765,7 +765,7 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection * regarding this resync process. * Proper fix would be to make resync itself lazy, i.e. only happen * when actually needed. - * See also T73411. + * See also #73411. * \{ */ static bool no_resync = false; diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index fcf585dfcfc..d09511ec4b3 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -1810,7 +1810,7 @@ void BKE_library_make_local(Main *bmain, /* Step 4: We have to remap local usages of old (linked) ID to new (local) * ID in a separated loop, * as lbarray ordering is not enough to ensure us we did catch all dependencies - * (e.g. if making local a parent object before its child...). See T48907. */ + * (e.g. if making local a parent object before its child...). See #48907. */ /* TODO: This is now the biggest step by far (in term of processing time). * We may be able to gain here by using again main->relations mapping, but... * this implies BKE_libblock_remap & co to be able to update main->relations on the fly. @@ -1828,7 +1828,7 @@ void BKE_library_make_local(Main *bmain, /* Special hack for groups... Thing is, since we can't instantiate them here, we need to * ensure they remain 'alive' (only instantiation is a real group 'user'... *sigh* See - * T49722. */ + * #49722. */ if (GS(id->name) == ID_GR && (id->tag & LIB_TAG_INDIRECT) != 0) { id_us_ensure_real(id->newid); } diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 8a9440a8e32..065ee010e72 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -396,7 +396,7 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, ID *local_id = lib_override_library_create_from(bmain, nullptr, reference_id, 0); /* We cannot allow automatic hierarchy resync on this ID, it is highly likely to generate a giant * mess in case there are a lot of hidden, non-instantiated, non-properly organized dependencies. - * Ref T94650. */ + * Ref #94650. */ local_id->override_library->flag |= IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY; local_id->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; local_id->override_library->hierarchy_root = local_id; @@ -2105,7 +2105,7 @@ static bool lib_override_library_resync(Main *bmain, if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && id->override_library->reference->lib->id.tag & LIB_TAG_MISSING) { /* Do not delete overrides which reference is missing because the library itself is missing - * (ref. T100586). */ + * (ref. #100586). */ } else if (!BKE_lib_override_library_is_user_edited(id)) { /* If user never edited them, we can delete them. */ @@ -2720,7 +2720,7 @@ void BKE_lib_override_library_main_resync(Main *bmain, /* Necessary to improve performances, and prevent layers matching override sub-collections to be * lost when re-syncing the parent override collection. - * Ref. T73411. */ + * Ref. #73411. */ BKE_layer_collection_resync_forbid(); int library_indirect_level = lib_override_libraries_index_define(bmain); diff --git a/source/blender/blenkernel/intern/lib_override_proxy_conversion.c b/source/blender/blenkernel/intern/lib_override_proxy_conversion.c index 88f6fbb0ead..deb75441b54 100644 --- a/source/blender/blenkernel/intern/lib_override_proxy_conversion.c +++ b/source/blender/blenkernel/intern/lib_override_proxy_conversion.c @@ -45,7 +45,7 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain, &ob_proxy->proxy->id; ID *id_instance_hint = is_override_instancing_object ? &ob_proxy_group->id : &ob_proxy->id; - /* In some cases the instance collection of a proxy object may be local (see e.g. T83875). Not + /* In some cases the instance collection of a proxy object may be local (see e.g. #83875). Not * sure this is a valid state, but for now just abort the overriding process. */ if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id_root)) { if (ob_proxy->proxy != NULL) { @@ -73,7 +73,7 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain, /* In case of proxy conversion, remap all local ID usages to linked IDs to their newly created * overrides. Also do that for the IDs from the same lib as the proxy in case it is linked. * While this might not be 100% the desired behavior, it is likely to be the case most of the - * time. Ref: T91711. */ + * time. Ref: #91711. */ ID *id_iter; FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { if (!ID_IS_LINKED(id_iter) || id_iter->lib == ob_proxy->id.lib) { diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 124ba21d406..4d6b78e67c4 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -165,7 +165,7 @@ void BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp) } else if (flag & IDWALK_RECURSE) { /* Defer handling into main loop, recursively calling BKE_library_foreach_ID_link in - * IDWALK_RECURSE case is troublesome, see T49553. */ + * IDWALK_RECURSE case is troublesome, see #49553. */ /* XXX note that this breaks the 'owner id' thing now, we likely want to handle that * differently at some point, but for now it should not be a problem in practice. */ if (BLI_gset_add(data->ids_handled, id)) { diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c index 127459508c2..4ef3bdabfaa 100644 --- a/source/blender/blenkernel/intern/lib_remap.c +++ b/source/blender/blenkernel/intern/lib_remap.c @@ -608,7 +608,7 @@ static void libblock_remap_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_ /* Node trees may virtually use any kind of data-block... */ /* XXX Yuck!!!! nodetree update can do pretty much any thing when talking about py nodes, - * including creating new data-blocks (see T50385), so we need to unlock main here. :( + * including creating new data-blocks (see #50385), so we need to unlock main here. :( * Why can't we have re-entrent locks? */ BKE_main_unlock(bmain); libblock_remap_data_postprocess_nodetree_update(bmain, new_id); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index ee50c4ae753..7cb28f14f9e 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -121,7 +121,7 @@ void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath) /* Not essential but set `filepath_abs` is an absolute copy of value which * is more useful if its kept in sync. */ if (BLI_path_is_rel(lib->filepath_abs)) { - /* NOTE(@campbellbarton): the file may be unsaved, in this case, setting the + /* NOTE(@ideasman42): the file may be unsaved, in this case, setting the * `filepath_abs` on an indirectly linked path is not allowed from the * outliner, and its not really supported but allow from here for now * since making local could cause this to be directly linked. diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index 0fd3ec4f8cd..b34e92837a9 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -850,7 +850,7 @@ void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, boo ob->mat = newmatar; ob->matbits = newmatbits; } - /* XXX(@campbellbarton): why not realloc on shrink? */ + /* XXX(@ideasman42): why not realloc on shrink? */ ob->totcol = totcol; if (ob->totcol && ob->actcol == 0) { @@ -877,7 +877,7 @@ void BKE_object_materials_test(Main *bmain, Object *ob, ID *id) /* Exception: In case the object is a valid data, but its obdata is an empty place-holder, * use object's material slots amount as reference. * This avoids losing materials in a local object when its linked obdata goes missing. - * See T92780. */ + * See #92780. */ BKE_id_material_resize(bmain, id, short(ob->totcol), false); } else { @@ -1311,7 +1311,7 @@ bool BKE_object_material_slot_remove(Main *bmain, Object *ob) for (Object *obt = static_cast(bmain->objects.first); obt; obt = static_cast(obt->id.next)) { if (obt->data == ob->data) { - /* Can happen when object material lists are used, see: T52953 */ + /* Can happen when object material lists are used, see: #52953 */ if (actcol > obt->totcol) { continue; } diff --git a/source/blender/blenkernel/intern/mball.cc b/source/blender/blenkernel/intern/mball.cc index c5025e51eb8..3a5e3104b86 100644 --- a/source/blender/blenkernel/intern/mball.cc +++ b/source/blender/blenkernel/intern/mball.cc @@ -277,7 +277,7 @@ bool BKE_mball_is_basis(const Object *ob) /* Meta-Ball Basis Notes from Blender-2.5x * ======================================= * - * NOTE(@campbellbarton): This is a can of worms. + * NOTE(@ideasman42): This is a can of worms. * * This really needs a rewrite/refactor its totally broken in anything other than basic cases * Multiple Scenes + Set Scenes & mixing meta-ball basis _should_ work but fails to update the @@ -485,7 +485,7 @@ bool BKE_mball_minmax_ex( copy_v3_v3(centroid, &ml->x); } - /* TODO(@campbellbarton): non circle shapes cubes etc, probably nobody notices. */ + /* TODO(@ideasman42): non circle shapes cubes etc, probably nobody notices. */ for (int i = -1; i != 3; i += 2) { copy_v3_v3(vec, centroid); add_v3_fl(vec, scale_mb * i); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index f588bfb1326..5b4c4edd0a2 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -107,10 +107,12 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int mesh_dst->runtime->wrapper_type_finalize = mesh_src->runtime->wrapper_type_finalize; mesh_dst->runtime->subsurf_runtime_data = mesh_src->runtime->subsurf_runtime_data; mesh_dst->runtime->cd_mask_extra = mesh_src->runtime->cd_mask_extra; - /* Copy face dot tags, since meshes may be duplicated after a subsurf modifier or node, but we - * still need to be able to draw face center vertices. The tags may be cleared explicitly when - * the topology is changed. */ + /* Copy face dot tags and edge tags, since meshes may be duplicated after a subsurf modifier or + * node, but we still need to be able to draw face center vertices and "optimal edges" + * differently. The tags may be cleared explicitly when the topology is changed. */ mesh_dst->runtime->subsurf_face_dot_tags = mesh_src->runtime->subsurf_face_dot_tags; + mesh_dst->runtime->subsurf_optimal_display_edges = + mesh_src->runtime->subsurf_optimal_display_edges; if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) { /* This is a direct copy of a main mesh, so for now it has the same topology. */ mesh_dst->runtime->deformed_only = true; @@ -905,7 +907,7 @@ void BKE_mesh_free_data_for_undo(Mesh *me) * * - Edit-Mesh (#Mesh.edit_mesh) * Since edit-mesh is tied to the objects mode, - * which crashes when called in edit-mode, see: T90972. + * which crashes when called in edit-mode, see: #90972. */ static void mesh_clear_geometry(Mesh *mesh) { diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index ddca932c648..f186d89a4e5 100644 --- a/source/blender/blenkernel/intern/mesh_calc_edges.cc +++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc @@ -146,7 +146,6 @@ static void serialize_and_initialize_deduplicated_edges(MutableSpan edg /* Initialize new edge. */ new_edge.v1 = item.key.v_low; new_edge.v2 = item.key.v_high; - new_edge.flag = ME_EDGEDRAW; } item.value.index = new_edge_index; new_edge_index++; @@ -177,7 +176,7 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh, else { /* This is an invalid edge; normally this does not happen in Blender, * but it can be part of an imported mesh with invalid geometry. See - * T76514. */ + * #76514. */ edge_index = 0; } prev_loop->e = edge_index; diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 0a2c8a714e3..5c71ffea0fa 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -121,7 +121,7 @@ static void make_edges_mdata_extend(Mesh &mesh) BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2); BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index)); - medge->flag = ME_EDGEDRAW; + medge->flag = 0; } BLI_edgehashIterator_free(ehi); @@ -223,7 +223,6 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba for (b = 1; b < dl->nr; b++) { edges[dst_edge].v1 = startvert + ofs + b - 1; edges[dst_edge].v2 = startvert + ofs + b; - edges[dst_edge].flag = ME_EDGEDRAW; dst_edge++; } @@ -250,7 +249,6 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba else { edges[dst_edge].v2 = startvert + ofs + b + 1; } - edges[dst_edge].flag = ME_EDGEDRAW; dst_edge++; } } @@ -662,14 +660,6 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me) &pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint); } -void BKE_mesh_edges_set_draw_render(Mesh *mesh) -{ - MutableSpan edges = mesh->edges_for_write(); - for (int i = 0; i < mesh->totedge; i++) { - edges[i].flag |= ME_EDGEDRAW; - } -} - void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob) { BLI_assert(ob->type == OB_POINTCLOUD); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 3c25cd2e07e..d6f40a472de 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -154,7 +154,7 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly, /** * A version of mesh_calc_poly_volume_centroid that takes an initial reference center, * use this to increase numeric stability as the quality of the result becomes - * very low quality as the value moves away from 0.0, see: T65986. + * very low quality as the value moves away from 0.0, see: #65986. */ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *mpoly, const MLoop *loopstart, diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index b789fbcc0a0..92197800aea 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -89,7 +89,6 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/, int totface, int /*totloop*/, int totpoly, - const bool use_old, MEdge **r_medge, int *r_totedge) { @@ -156,9 +155,6 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/, if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) { med->v1 = ed->v1; med->v2 = ed->v2; - if (use_old == false || ed->is_draw) { - med->flag = ME_EDGEDRAW; - } /* order is swapped so extruding this edge as a surface won't flip face normals * with cyclic curves */ @@ -175,7 +171,6 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/, /* last edge */ med->v1 = ed->v1; med->v2 = ed->v2; - med->flag = ME_EDGEDRAW; MEM_freeN(edsort); @@ -206,7 +201,7 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/, *r_totedge = totedge_final; } -void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) +void BKE_mesh_calc_edges_legacy(Mesh *me) { using namespace blender; MEdge *medge; @@ -224,7 +219,6 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) me->totface, loops.size(), polys.size(), - use_old, &medge, &totedge); @@ -657,7 +651,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) { if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) { /* Pass, otherwise this function clears 'mface' before - * versioning 'mface -> mpoly' code kicks in T30583. + * versioning 'mface -> mpoly' code kicks in #30583. * * Callers could also check but safer to do here - campbell */ } diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 780e32d540a..427f3a44ddf 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -15,6 +15,7 @@ #include "BLI_array.hh" #include "BLI_bitmap.h" #include "BLI_buffer.h" +#include "BLI_function_ref.hh" #include "BLI_math.h" #include "BLI_task.hh" #include "BLI_utildefines.h" @@ -385,7 +386,6 @@ void BKE_mesh_vert_edge_vert_map_create( void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, int **r_mem, - const MEdge * /*medge*/, const int totedge, const MPoly *mpoly, const int totpoly, @@ -438,7 +438,6 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map, void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int **r_mem, - const MEdge * /*medge*/, const int totedge, const MPoly *mpoly, const int totpoly, @@ -610,6 +609,20 @@ Array> build_edge_to_loop_map(const Span loops, const int edg return map; } +Array> build_edge_to_poly_map(const Span polys, + const Span loops, + const int edges_num) +{ + Array> map(edges_num); + for (const int64_t i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + map[loop.e].append(int(i)); + } + } + return map; +} + Vector> build_edge_to_loop_map_resizable(const Span loops, const int edges_num) { Vector> map(edges_num); @@ -631,27 +644,19 @@ Vector> build_edge_to_loop_map_resizable(const Span loops, co /** * Callback deciding whether the given poly/loop/edge define an island boundary or not. */ -using MeshRemap_CheckIslandBoundary = bool (*)(const MPoly *mpoly, - const MLoop *mloop, - const MEdge *medge, - const int edge_index, - const bool *sharp_edges, - const int edge_user_count, - const MPoly *mpoly_array, - const MeshElemMap *edge_poly_map, - void *user_data); +using MeshRemap_CheckIslandBoundary = + blender::FunctionRef; -static void poly_edge_loop_islands_calc(const MEdge *medge, - const int totedge, - const MPoly *mpoly, - const int totpoly, - const MLoop *mloop, - const int totloop, - const bool *sharp_edges, +static void poly_edge_loop_islands_calc(const int totedge, + const blender::Span polys, + const blender::Span loops, MeshElemMap *edge_poly_map, const bool use_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check, - void *edge_boundary_check_data, int **r_poly_groups, int *r_totgroup, BLI_bitmap **r_edge_borders, @@ -675,7 +680,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, /* map vars */ int *edge_poly_mem = nullptr; - if (totpoly == 0) { + if (polys.size() == 0) { *r_totgroup = 0; *r_poly_groups = nullptr; if (r_edge_borders) { @@ -691,12 +696,17 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, } if (!edge_poly_map) { - BKE_mesh_edge_poly_map_create( - &edge_poly_map, &edge_poly_mem, medge, totedge, mpoly, totpoly, mloop, totloop); + BKE_mesh_edge_poly_map_create(&edge_poly_map, + &edge_poly_mem, + totedge, + polys.data(), + int(polys.size()), + loops.data(), + int(loops.size())); } - poly_groups = static_cast(MEM_callocN(sizeof(int) * size_t(totpoly), __func__)); - poly_stack = static_cast(MEM_mallocN(sizeof(int) * size_t(totpoly), __func__)); + poly_groups = static_cast(MEM_callocN(sizeof(int) * size_t(polys.size()), __func__)); + poly_stack = static_cast(MEM_mallocN(sizeof(int) * size_t(polys.size()), __func__)); while (true) { int poly; @@ -704,13 +714,13 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, int poly_group_id; int ps_curr_idx = 0, ps_end_idx = 0; /* stack indices */ - for (poly = poly_prev; poly < totpoly; poly++) { + for (poly = poly_prev; poly < int(polys.size()); poly++) { if (poly_groups[poly] == 0) { break; } } - if (poly == totpoly) { + if (poly == int(polys.size())) { /* all done */ break; } @@ -724,23 +734,16 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, poly_stack[ps_end_idx++] = poly; while (ps_curr_idx != ps_end_idx) { - const MPoly *mp; - const MLoop *ml; - int j; - poly = poly_stack[ps_curr_idx++]; BLI_assert(poly_groups[poly] == poly_group_id); - mp = &mpoly[poly]; - for (ml = &mloop[mp->loopstart], j = mp->totloop; j--; ml++) { + for (const int64_t loop : blender::IndexRange(polys[poly].loopstart, polys[poly].totloop)) { + const int edge = int(loops[loop].e); /* loop over poly users */ - const int me_idx = int(ml->e); - const MEdge *me = &medge[me_idx]; - const MeshElemMap *map_ele = &edge_poly_map[me_idx]; - const int *p = map_ele->indices; - int i = map_ele->count; - if (!edge_boundary_check( - mp, ml, me, me_idx, sharp_edges, i, mpoly, map_ele, edge_boundary_check_data)) { + const MeshElemMap &map_ele = edge_poly_map[edge]; + const int *p = map_ele.indices; + int i = map_ele.count; + if (!edge_boundary_check(poly, int(loop), edge, i, map_ele)) { for (; i--; p++) { /* if we meet other non initialized its a bug */ BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id)); @@ -752,8 +755,8 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, } } else { - if (edge_borders && !BLI_BITMAP_TEST(edge_borders, me_idx)) { - BLI_BITMAP_ENABLE(edge_borders, me_idx); + if (edge_borders && !BLI_BITMAP_TEST(edge_borders, edge)) { + BLI_BITMAP_ENABLE(edge_borders, edge); num_edgeborders++; } if (use_bitflags) { @@ -814,7 +817,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, } if (UNLIKELY(group_id_overflow)) { - int i = totpoly, *gid = poly_groups; + int i = int(polys.size()), *gid = poly_groups; for (; i--; gid++) { if (*gid == poly_group_id_overflowed) { *gid = 0; @@ -838,31 +841,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, } } -static bool poly_is_island_boundary_smooth_cb(const MPoly *mp, - const MLoop * /*ml*/, - const MEdge * /*me*/, - const int edge_index, - const bool *sharp_edges, - const int edge_user_count, - const MPoly *mpoly_array, - const MeshElemMap *edge_poly_map, - void * /*user_data*/) -{ - /* Edge is sharp if one of its polys is flat, or edge itself is sharp, - * or edge is not used by exactly two polygons. */ - if ((mp->flag & ME_SMOOTH) && !(sharp_edges && sharp_edges[edge_index]) && - (edge_user_count == 2)) { - /* In that case, edge appears to be smooth, but we need to check its other poly too. */ - const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ? - &mpoly_array[edge_poly_map->indices[1]] : - &mpoly_array[edge_poly_map->indices[0]]; - return (mp_other->flag & ME_SMOOTH) == 0; - } - return true; -} - -int *BKE_mesh_calc_smoothgroups(const MEdge *medge, - const int totedge, +int *BKE_mesh_calc_smoothgroups(const int totedge, const MPoly *mpoly, const int totpoly, const MLoop *mloop, @@ -873,17 +852,30 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, { int *poly_groups = nullptr; - poly_edge_loop_islands_calc(medge, - totedge, - mpoly, - totpoly, - mloop, - totloop, - sharp_edges, + auto poly_is_island_boundary_smooth = [&](const int poly_index, + const int /*loop_index*/, + const int edge_index, + const int edge_user_count, + const MeshElemMap &edge_poly_map_elem) { + /* Edge is sharp if one of its polys is flat, or edge itself is sharp, + * or edge is not used by exactly two polygons. */ + if ((mpoly[poly_index].flag & ME_SMOOTH) && !(sharp_edges && sharp_edges[edge_index]) && + (edge_user_count == 2)) { + /* In that case, edge appears to be smooth, but we need to check its other poly too. */ + const int other_poly_index = (poly_index == edge_poly_map_elem.indices[0]) ? + edge_poly_map_elem.indices[1] : + edge_poly_map_elem.indices[0]; + return (mpoly[other_poly_index].flag & ME_SMOOTH) == 0; + } + return true; + }; + + poly_edge_loop_islands_calc(totedge, + {mpoly, totpoly}, + {mloop, totloop}, nullptr, use_bitflags, - poly_is_island_boundary_smooth_cb, - nullptr, + poly_is_island_boundary_smooth, &poly_groups, r_totgroup, nullptr, @@ -1007,64 +999,6 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, sizeof(*innrcut->indices) * size_t(num_innercut_items)); } -/* TODO: I'm not sure edge seam flag is enough to define UV islands? - * Maybe we should also consider UV-maps values - * themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?). - * Would make things much more complex though, - * and each UVMap would then need its own mesh mapping, not sure we want that at all! - */ -struct MeshCheckIslandBoundaryUv { - const MLoop *loops; - const float (*luvs)[2]; - const MeshElemMap *edge_loop_map; -}; - -static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/, - const MLoop *ml, - const MEdge *me, - const int /*edge_index*/, - const bool * /*sharp_edges*/, - const int /*edge_user_count*/, - const MPoly * /*mpoly_array*/, - const MeshElemMap * /*edge_poly_map*/, - void *user_data) -{ - if (user_data) { - const MeshCheckIslandBoundaryUv *data = static_cast( - user_data); - const MLoop *loops = data->loops; - const float(*luvs)[2] = data->luvs; - const MeshElemMap *edge_to_loops = &data->edge_loop_map[ml->e]; - - BLI_assert(edge_to_loops->count >= 2 && (edge_to_loops->count % 2) == 0); - - const uint v1 = loops[edge_to_loops->indices[0]].v; - const uint v2 = loops[edge_to_loops->indices[1]].v; - const float *uvco_v1 = luvs[edge_to_loops->indices[0]]; - const float *uvco_v2 = luvs[edge_to_loops->indices[1]]; - for (int i = 2; i < edge_to_loops->count; i += 2) { - if (loops[edge_to_loops->indices[i]].v == v1) { - if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]]) || - !equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]])) { - return true; - } - } - else { - BLI_assert(loops[edge_to_loops->indices[i]].v == v2); - UNUSED_VARS_NDEBUG(v2); - if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]]) || - !equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]])) { - return true; - } - } - } - return false; - } - - /* Edge is UV boundary if tagged as seam. */ - return (me->flag & ME_SEAM) != 0; -} - static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges, const int totedge, const MPoly *polys, @@ -1084,8 +1018,6 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges, MeshElemMap *edge_loop_map; int *edge_loop_mem; - MeshCheckIslandBoundaryUv edge_boundary_check_data; - int *poly_indices; int *loop_indices; int num_pidx, num_lidx; @@ -1106,27 +1038,62 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges, r_island_store, MISLAND_TYPE_LOOP, totloop, MISLAND_TYPE_POLY, MISLAND_TYPE_EDGE); BKE_mesh_edge_poly_map_create( - &edge_poly_map, &edge_poly_mem, edges, totedge, polys, totpoly, loops, totloop); + &edge_poly_map, &edge_poly_mem, totedge, polys, totpoly, loops, totloop); if (luvs) { BKE_mesh_edge_loop_map_create( - &edge_loop_map, &edge_loop_mem, edges, totedge, polys, totpoly, loops, totloop); - edge_boundary_check_data.loops = loops; - edge_boundary_check_data.luvs = luvs; - edge_boundary_check_data.edge_loop_map = edge_loop_map; + &edge_loop_map, &edge_loop_mem, totedge, polys, totpoly, loops, totloop); } - poly_edge_loop_islands_calc(edges, - totedge, - polys, - totpoly, - loops, - totloop, - nullptr, + /* TODO: I'm not sure edge seam flag is enough to define UV islands? + * Maybe we should also consider UV-maps values + * themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?). + * Would make things much more complex though, + * and each UVMap would then need its own mesh mapping, not sure we want that at all! + */ + auto mesh_check_island_boundary_uv = [&](const int /*poly_index*/, + const int loop_index, + const int edge_index, + const int /*edge_user_count*/, + const MeshElemMap & /*edge_poly_map_elem*/) -> bool { + if (luvs) { + const MeshElemMap &edge_to_loops = edge_loop_map[loops[loop_index].e]; + + BLI_assert(edge_to_loops.count >= 2 && (edge_to_loops.count % 2) == 0); + + const uint v1 = loops[edge_to_loops.indices[0]].v; + const uint v2 = loops[edge_to_loops.indices[1]].v; + const float *uvco_v1 = luvs[edge_to_loops.indices[0]]; + const float *uvco_v2 = luvs[edge_to_loops.indices[1]]; + for (int i = 2; i < edge_to_loops.count; i += 2) { + if (loops[edge_to_loops.indices[i]].v == v1) { + if (!equals_v2v2(uvco_v1, luvs[edge_to_loops.indices[i]]) || + !equals_v2v2(uvco_v2, luvs[edge_to_loops.indices[i + 1]])) { + return true; + } + } + else { + BLI_assert(loops[edge_to_loops.indices[i]].v == v2); + UNUSED_VARS_NDEBUG(v2); + if (!equals_v2v2(uvco_v2, luvs[edge_to_loops.indices[i]]) || + !equals_v2v2(uvco_v1, luvs[edge_to_loops.indices[i + 1]])) { + return true; + } + } + } + return false; + } + + /* Edge is UV boundary if tagged as seam. */ + return (edges[edge_index].flag & ME_SEAM) != 0; + }; + + poly_edge_loop_islands_calc(totedge, + {polys, totpoly}, + {loops, totloop}, edge_poly_map, false, mesh_check_island_boundary_uv, - luvs ? &edge_boundary_check_data : nullptr, &poly_groups, &num_poly_groups, &edge_borders, diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc index 99a45b137a4..c10c9d851b9 100644 --- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc +++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc @@ -34,7 +34,7 @@ static int compare_v2_classify(const float uv_a[2], const float uv_b[2]) if (uv_a[0] == uv_b[0] && uv_a[1] == uv_b[1]) { return CMP_EQUAL; } - /* NOTE(@campbellbarton): that the ULP value is the primary value used to compare relative + /* NOTE(@ideasman42): that the ULP value is the primary value used to compare relative * values as the absolute value doesn't account for float precision at difference scales. * - For subdivision-surface ULP of 3 is sufficient, * although this value is extremely small. diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 95f8008a4f9..3c603a5a1f3 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -161,7 +161,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, copy_v3_v3(plane_co, itmp[3]); copy_v3_v3(plane_no, itmp[axis]); - /* Account for non-uniform scale in `ob`, see: T87592. */ + /* Account for non-uniform scale in `ob`, see: #87592. */ float ob_scale[3] = { len_squared_v3(ob->object_to_world[0]), len_squared_v3(ob->object_to_world[1]), @@ -248,7 +248,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, * generate a 1:1 mapping by scanning vertices from the beginning of the array * as is done in #BKE_editmesh_vert_coords_when_deformed. Without this, * the coordinates returned will sometimes point to the copied vertex locations, see: - * T91444. + * #91444. * * However, such a change also affects non-versionable things like some modifiers binding, so * we cannot enforce that behavior on existing modifiers, in which case we keep using the diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 22b6ce5222c..c83de7a843a 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -1749,7 +1749,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], /* We also have to check between last and first loops, * otherwise we may miss some sharp edges here! * This is just a simplified version of above while loop. - * See T45984. */ + * See #45984. */ loops = lnors_spacearr.lspacearr[i]->loops; if (loops && org_nor) { const int lidx = POINTER_AS_INT(loops->link); diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index c32a9c067ac..8c25315ab19 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -1424,7 +1424,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, /* Needed for islands (or plain mesh) to AStar graph conversion. */ BKE_mesh_edge_poly_map_create(&edge_to_poly_map_src, &edge_to_poly_map_src_buff, - edges_src, num_edges_src, polys_src, num_polys_src, @@ -1667,7 +1666,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, if (dot > best_nor_dot - 1e-6f) { /* We need something as fallback decision in case dest normal matches several - * source normals (see T44522), using distance between polys' centers here. */ + * source normals (see #44522), using distance between polys' centers here. */ float *pcent_src; float sqdist; diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 3c64d7f3742..d1e56278c07 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -230,6 +230,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh) mesh->runtime->loose_edges_cache.tag_dirty(); mesh->runtime->looptris_cache.tag_dirty(); mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); + mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink(); if (mesh->runtime->shrinkwrap_data) { BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); } @@ -245,6 +246,7 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh) free_subdiv_ccg(*mesh->runtime); mesh->runtime->loose_edges_cache.tag_dirty(); mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); + mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink(); if (mesh->runtime->shrinkwrap_data) { BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); } diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 35c7c1f40bc..b0bc16b2732 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -573,7 +573,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len) { - /* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */ + /* TODO(@ideasman42): store in Mesh.runtime to avoid recalculation. */ short tangent_mask = 0; BKE_mesh_calc_loop_tangent_ex( BKE_mesh_vert_positions(me_eval), diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 478c429e7aa..0d6afdd4dd3 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -1356,8 +1356,6 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh) for (int i = 0; BLI_edgesetIterator_isDone(ehi) == false; BLI_edgesetIterator_step(ehi), i++, med++, index++) { BLI_edgesetIterator_getKey(ehi, &med->v1, &med->v2); - - med->flag = ME_EDGEDRAW; *index = ORIGINDEX_NONE; } BLI_edgesetIterator_free(ehi); diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 9c8c36cacb8..555ae98e2d8 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -350,7 +350,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me) BKE_mesh_calc_normals_split(subdiv_mesh); } - if (subdiv != runtime_data->subdiv) { + if (!ELEM(subdiv, runtime_data->subdiv_cpu, runtime_data->subdiv_gpu)) { BKE_subdiv_free(subdiv); } diff --git a/source/blender/blenkernel/intern/modifier.cc b/source/blender/blenkernel/intern/modifier.cc index 580c08a51ba..e82e9c0f559 100644 --- a/source/blender/blenkernel/intern/modifier.cc +++ b/source/blender/blenkernel/intern/modifier.cc @@ -1045,7 +1045,7 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval) if ((ob_eval->type == OB_MESH) && (ob_eval->mode & OB_MODE_EDIT)) { /* In EditMode, evaluated mesh is stored in BMEditMesh, not the object... */ BMEditMesh *em = BKE_editmesh_from_object(ob_eval); - /* 'em' might not exist yet in some cases, just after loading a .blend file, see T57878. */ + /* 'em' might not exist yet in some cases, just after loading a .blend file, see #57878. */ if (em != nullptr) { me = BKE_object_get_editmesh_eval_final(ob_eval); } diff --git a/source/blender/blenkernel/intern/multires_reshape_ccg.cc b/source/blender/blenkernel/intern/multires_reshape_ccg.cc index 97be97ae3c1..94751a37fc5 100644 --- a/source/blender/blenkernel/intern/multires_reshape_ccg.cc +++ b/source/blender/blenkernel/intern/multires_reshape_ccg.cc @@ -64,7 +64,7 @@ bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext * used by sculpt changes. In other use cases the code might not catch inconsistency and * silently do wrong decision. */ /* NOTE: There is a known bug in Undo code that results in first Sculpt step - * after a Memfile one to never be undone (see T83806). This might be the root cause of + * after a Memfile one to never be undone (see #83806). This might be the root cause of * this inconsistency. */ if (reshape_level_key.has_mask && grid_element.mask != nullptr) { *grid_element.mask = *CCG_grid_elem_mask(&reshape_level_key, ccg_grid, x, y); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 6b631462ebd..29d4cc802fe 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -61,7 +61,7 @@ static void nla_tweakmode_find_active(const ListBase /* NlaTrack */ *nla_tracks, /* Freeing ------------------------------------------- */ -void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user) +void BKE_nlastrip_free(NlaStrip *strip, const bool do_id_user) { NlaStrip *cs, *csn; @@ -73,7 +73,7 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user) /* free child-strips */ for (cs = strip->strips.first; cs; cs = csn) { csn = cs->next; - BKE_nlastrip_free(&strip->strips, cs, do_id_user); + BKE_nlastrip_remove_and_free(&strip->strips, cs, do_id_user); } /* remove reference to action */ @@ -81,10 +81,6 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user) id_us_min(&strip->act->id); } - /* free remapping info */ - // if (strip->remap) - // BKE_animremap_free(); - /* free own F-Curves */ BKE_fcurves_free(&strip->fcurves); @@ -92,12 +88,7 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user) free_fmodifiers(&strip->modifiers); /* free the strip itself */ - if (strips) { - BLI_freelinkN(strips, strip); - } - else { - MEM_freeN(strip); - } + MEM_freeN(strip); } void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user) @@ -112,7 +103,7 @@ void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user) /* free strips */ for (strip = nlt->strips.first; strip; strip = stripn) { stripn = strip->next; - BKE_nlastrip_free(&nlt->strips, strip, do_id_user); + BKE_nlastrip_remove_and_free(&nlt->strips, strip, do_id_user); } /* free NLA track itself now */ @@ -875,7 +866,7 @@ void BKE_nlastrips_clear_metastrip(ListBase *strips, NlaStrip *strip) } /* free the meta-strip now */ - BKE_nlastrip_free(strips, strip, true); + BKE_nlastrip_remove_and_free(strips, strip, true); } void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp) @@ -1190,6 +1181,12 @@ bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_libove return BKE_nlastrips_add_strip(&nlt->strips, strip); } +void BKE_nlatrack_remove_strip(NlaTrack *track, NlaStrip *strip) +{ + BLI_assert(track); + BKE_nlastrip_remove(&track->strips, strip); +} + bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2]) { NlaStrip *strip; @@ -1318,6 +1315,18 @@ NlaStrip *BKE_nlastrip_find_active(NlaTrack *nlt) return nlastrip_find_active(&nlt->strips); } +void BKE_nlastrip_remove(ListBase *strips, NlaStrip *strip) +{ + BLI_assert(strips); + BLI_remlink(strips, strip); +} + +void BKE_nlastrip_remove_and_free(ListBase *strips, NlaStrip *strip, const bool do_id_user) +{ + BKE_nlastrip_remove(strips, strip); + BKE_nlastrip_free(strip, do_id_user); +} + void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip) { NlaTrack *nlt; @@ -2009,8 +2018,7 @@ void BKE_nla_action_pushdown(AnimData *adt, const bool is_liboverride) /* copy current "action blending" settings from adt to the strip, * as it was keyframed with these settings, so omitting them will - * change the effect [T54233] - */ + * change the effect [#54233]. */ strip->blendmode = adt->act_blendmode; strip->influence = adt->act_influence; strip->extendmode = adt->act_extendmode; @@ -2058,7 +2066,7 @@ static void nla_tweakmode_find_active(const ListBase /* NlaTrack */ *nla_tracks, /* There are situations where we may have multiple strips selected and we want to enter * tweak-mode on all of those at once. Usually in those cases, * it will usually just be a single strip per AnimData. - * In such cases, compromise and take the last selected track and/or last selected strip, T28468. + * In such cases, compromise and take the last selected track and/or last selected strip, #28468. */ if (activeTrack == NULL) { /* try last selected track for active strip */ @@ -2178,7 +2186,7 @@ void BKE_nla_tweakmode_exit(AnimData *adt) /* sync the length of the user-strip with the new state of the action * but only if the user has explicitly asked for this to happen - * (see T34645 for things to be careful about) + * (see #34645 for things to be careful about) */ if ((adt->actstrip) && (adt->actstrip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) { strip = adt->actstrip; diff --git a/source/blender/blenkernel/intern/nla_test.cc b/source/blender/blenkernel/intern/nla_test.cc index ef9ca83e25f..3311ca82098 100644 --- a/source/blender/blenkernel/intern/nla_test.cc +++ b/source/blender/blenkernel/intern/nla_test.cc @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later * Copyright 2023 Blender Foundation. All rights reserved. */ +#include "BLI_listbase.h" + #include "BKE_nla.h" #include "DNA_anim_types.h" @@ -20,19 +22,19 @@ TEST(nla_strip, BKE_nlastrip_recalculate_blend) strip.start = 1; strip.end = 10; - /* Scaling a strip up doesn't affect the blend in/out value */ + /* Scaling a strip up doesn't affect the blend in/out value. */ strip.end = 20; BKE_nlastrip_recalculate_blend(&strip); EXPECT_FLOAT_EQ(strip.blendin, 4.0); EXPECT_FLOAT_EQ(strip.blendout, 5.0); - /* Scaling a strip down affects the blend-in value before the blend-out value */ + /* Scaling a strip down affects the blend-in value before the blend-out value. */ strip.end = 7; BKE_nlastrip_recalculate_blend(&strip); EXPECT_FLOAT_EQ(strip.blendin, 1.0); EXPECT_FLOAT_EQ(strip.blendout, 5.0); - /* Scaling a strip down to nothing updates the blend in/out values accordingly */ + /* Scaling a strip down to nothing updates the blend in/out values accordingly. */ strip.end = 1.1; BKE_nlastrip_recalculate_blend(&strip); EXPECT_FLOAT_EQ(strip.blendin, 0.0); @@ -63,4 +65,31 @@ TEST(nla_strip, BKE_nlastrips_add_strip) EXPECT_TRUE(BKE_nlastrips_add_strip(&strips, &strip2)); } +TEST(nla_track, BKE_nlatrack_remove_strip) +{ + NlaTrack track{}; + ListBase strips{}; + NlaStrip strip1{}; + strip1.start = 0; + strip1.end = 10; + + NlaStrip strip2{}; + strip2.start = 11; + strip2.end = 20; + + // Add NLA strips to the NLATrack. + BKE_nlastrips_add_strip(&strips, &strip1); + BKE_nlastrips_add_strip(&strips, &strip2); + track.strips = strips; + + // ensure we have 2 strips in the track. + EXPECT_EQ(2, BLI_listbase_count(&track.strips)); + + BKE_nlatrack_remove_strip(&track, &strip2); + EXPECT_EQ(1, BLI_listbase_count(&track.strips)); + // ensure the correct strip was removed. + EXPECT_EQ(-1, BLI_findindex(&track.strips, &strip2)); +} + } // namespace blender::bke::tests + diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 74351022fd3..7c3055c41e5 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -406,7 +406,7 @@ static ID **node_owner_pointer_get(ID *id) if ((id->flag & LIB_EMBEDDED_DATA) == 0) { return nullptr; } - /* TODO: Sort this NO_MAIN or not for embedded node trees. See T86119. */ + /* TODO: Sort this NO_MAIN or not for embedded node trees. See #86119. */ // BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0); bNodeTree *ntree = reinterpret_cast(id); @@ -542,7 +542,7 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) /* pass */ } else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_GLARE)) { - /* Simple forward compatibility for fix for T50736. + /* Simple forward compatibility for fix for #50736. * Not ideal (there is no ideal solution here), but should do for now. */ NodeGlare *ndg = (NodeGlare *)node->storage; /* Not in undo case. */ @@ -838,7 +838,7 @@ static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSock IDP_BlendReadLib(reader, lib, sock->prop); /* This can happen for all socket types when a file is saved in an older version of Blender than - * it was originally created in (T86298). Some socket types still require a default value. The + * it was originally created in (#86298). Some socket types still require a default value. The * default value of those sockets will be created in `ntreeSetTypes`. */ if (sock->default_value == nullptr) { return; @@ -2342,8 +2342,10 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree, node_dst->typeinfo->copyfunc_api(&ptr, &node_src); } - /* Reset the declaration of the new node. */ - nodeDeclarationEnsure(dst_tree, node_dst); + /* Reset the declaration of the new node in real tree. */ + if (dst_tree != nullptr) { + nodeDeclarationEnsure(dst_tree, node_dst); + } return node_dst; } @@ -3107,7 +3109,7 @@ static void free_localized_node_groups(bNodeTree *ntree) /* Only localized node trees store a copy for each node group tree. * Each node group tree in a localized node tree can be freed, * since it is a localized copy itself (no risk of accessing free'd - * data in main, see T37939). */ + * data in main, see #37939). */ if (!(ntree->id.tag & LIB_TAG_LOCALIZED)) { return; } @@ -3455,21 +3457,41 @@ bNode *ntreeFindType(bNodeTree *ntree, int type) return nullptr; } -bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup) +static bool ntree_contains_tree_exec(const bNodeTree *tree_to_search_in, + const bNodeTree *tree_to_search_for, + Set &already_passed) { - if (ntree == lookup) { + if (tree_to_search_in == tree_to_search_for) { return true; } - for (const bNode *node : ntree->all_nodes()) { - if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) { - if (ntreeHasTree((bNodeTree *)node->id, lookup)) { - return true; - } + + tree_to_search_in->ensure_topology_cache(); + for (const bNode *node_group : tree_to_search_in->group_nodes()) { + const bNodeTree *sub_tree_search_in = reinterpret_cast(node_group->id); + if (!sub_tree_search_in) { + continue; + } + if (!already_passed.add(sub_tree_search_in)) { + continue; + } + if (ntree_contains_tree_exec(sub_tree_search_in, tree_to_search_for, already_passed)) { + return true; } } + return false; } +bool ntreeContainsTree(const bNodeTree *tree_to_search_in, const bNodeTree *tree_to_search_for) +{ + if (tree_to_search_in == tree_to_search_for) { + return true; + } + + Set already_passed; + return ntree_contains_tree_exec(tree_to_search_in, tree_to_search_for, already_passed); +} + bNodeLink *nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to) { LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { @@ -3617,6 +3639,8 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node) return false; } if (node->typeinfo->declare_dynamic) { + BLI_assert(ntree != nullptr); + BLI_assert(node != nullptr); node->runtime->declaration = new blender::nodes::NodeDeclaration(); blender::nodes::build_node_declaration_dynamic(*ntree, *node, *node->runtime->declaration); return true; diff --git a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc index af282485671..abe5f736eba 100644 --- a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc +++ b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc @@ -119,7 +119,7 @@ static const FieldInferencingInterface &get_node_field_inferencing_interface(con return empty_interface; } if (!ntreeIsRegistered(group)) { - /* This can happen when there is a linked node group that was not found (see T92799). */ + /* This can happen when there is a linked node group that was not found (see #92799). */ return get_dummy_field_inferencing_interface(node, scope); } if (!group->runtime->field_inferencing_interface) { diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 3534156c3fd..97114c6c624 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -622,7 +622,7 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id) const bool is_undo = BLO_read_data_is_undo(reader); if (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT)) { /* Do not allow any non-object mode for linked data. - * See T34776, T42780, T81027 for more information. */ + * See #34776, #42780, #81027 for more information. */ ob->mode &= ~OB_MODE_ALL_MODE_DATA; } else if (is_undo) { @@ -939,7 +939,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id) } /* When the object is local and the data is library its possible - * the material list size gets out of sync. T22663. */ + * the material list size gets out of sync. #22663. */ if (ob->data && ob->id.lib != ((ID *)ob->data)->lib) { BKE_object_materials_test(bmain, ob, (ID *)ob->data); } @@ -2432,7 +2432,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag); } - /* XXX(@campbellbarton): from reading existing code this seems correct but intended usage of + /* XXX(@ideasman42): from reading existing code this seems correct but intended usage of * point-cache should with cloth should be added in 'ParticleSystem'. */ if (psysn->clmd) { psysn->clmd->point_cache = psysn->pointcache; @@ -3151,7 +3151,7 @@ static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4]) * dependency cycles. We can't correct anything from here, since that would * cause threading conflicts. * - * TODO(sergey): Some of the legit looking cases like T56619 need to be + * TODO(sergey): Some of the legit looking cases like #56619 need to be * looked into, and maybe curve cache (and other dependencies) are to be * evaluated prior to conversion. */ if (par->runtime.curve_cache == nullptr) { @@ -3556,7 +3556,7 @@ void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *o * are supposed to be applied after the object's local loc/rot/scale. If the (inverted) effect of * constraints would be included in the parent inverse matrix, these would be applied before the * object's local loc/rot/scale instead of after. For example, a "Copy Rotation" constraint would - * rotate the object's local translation as well. See T82156. */ + * rotate the object's local translation as well. See #82156. */ BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr)); diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index fe83daef7a6..ebbd4bc61da 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -117,7 +117,7 @@ struct DupliContext { * decisions. However, new code uses geometry instances in places that weren't using the dupli * system previously. To fix this, keep track of the last dupli generator type that wasn't a * geometry set instance. - * */ + */ Vector *dupli_gen_type_stack; int persistent_id[MAX_DUPLI_RECUR]; @@ -1535,7 +1535,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem } if (part->ren_as == PART_DRAW_GR) { - /* Prevent divide by zero below T28336. */ + /* Prevent divide by zero below #28336. */ if (totcollection == 0) { continue; } diff --git a/source/blender/blenkernel/intern/object_update.cc b/source/blender/blenkernel/intern/object_update.cc index 5abd5188d1e..e5bb1b529df 100644 --- a/source/blender/blenkernel/intern/object_update.cc +++ b/source/blender/blenkernel/intern/object_update.cc @@ -149,7 +149,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o cddata_masks.pmask |= CD_MASK_PROP_ALL; cddata_masks.lmask |= CD_MASK_PROP_ALL; - /* Make sure Freestyle edge/face marks appear in DM for render (see T40315). + /* Make sure Freestyle edge/face marks appear in DM for render (see #40315). * Due to Line Art implementation, edge marks should also be shown in viewport. */ #ifdef WITH_FREESTYLE cddata_masks.emask |= CD_MASK_FREESTYLE_EDGE; diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index bcf382b6022..66b7f417807 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -222,9 +222,9 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float j1 = j1 % oc->_N; # define BILERP(m) \ - (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \ - interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \ - frac_z)) + interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \ + interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \ + frac_z) { if (oc->_do_disp_y) { @@ -1382,7 +1382,7 @@ void BKE_ocean_bake(struct Ocean *o, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data) { - /* NOTE(@campbellbarton): some of these values remain uninitialized unless certain options + /* NOTE(@ideasman42): some of these values remain uninitialized unless certain options * are enabled, take care that #BKE_ocean_eval_ij() initializes a member before use. */ OceanResult ocr; @@ -1437,7 +1437,7 @@ void BKE_ocean_bake(struct Ocean *o, rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp); if (o->_do_jacobian) { - /* TODO(@campbellbarton): cleanup unused code. */ + /* TODO(@ideasman42): cleanup unused code. */ float /* r, */ /* UNUSED */ pr = 0.0f, foam_result; float neg_disp, neg_eplus; diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 0c9d9f5b048..4399a65276a 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -878,7 +878,7 @@ void BKE_packedfile_blend_read(BlendDataReader *reader, PackedFile **pf_p) BLO_read_packed_address(reader, &pf->data); if (pf->data == NULL) { /* We cannot allow a PackedFile with a NULL data field, - * the whole code assumes this is not possible. See T70315. */ + * the whole code assumes this is not possible. See #70315. */ printf("%s: NULL packedfile data, cleaning up...\n", __func__); MEM_SAFE_FREE(pf); } diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 0ee517311d2..3ec6525ac6b 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1424,7 +1424,7 @@ void BKE_sculptsession_bm_to_me(Object *ob, bool reorder) sculptsession_bm_to_me_update_data_only(ob, reorder); /* Ensure the objects evaluated mesh doesn't hold onto arrays - * now realloc'd in the mesh T34473. */ + * now realloc'd in the mesh #34473. */ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } } diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 514accf098b..28be787a191 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -847,7 +847,7 @@ void psys_find_group_weights(ParticleSettings *part) { /* Find object pointers based on index. If the collection is linked from * another library linking may not have the object pointers available on - * file load, so we have to retrieve them later. See T49273. */ + * file load, so we have to retrieve them later. See #49273. */ ListBase instance_collection_objects = {nullptr, nullptr}; if (part->instance_collection) { @@ -3035,7 +3035,7 @@ static void psys_thread_create_path(ParticleTask *task, */ cpa_num = ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache; - /* XXX hack to avoid messed up particle num and subsequent crash (T40733) */ + /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ if (cpa_num > ctx->sim.psmd->mesh_final->totface) { cpa_num = 0; } @@ -5099,7 +5099,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, * the entire scenes dupli's are scanned, which also looks into uncalculated data. * * For now just include this workaround as an alternative to crashing, - * but longer term meta-balls should behave in a more manageable way, see: T46622. */ + * but longer term meta-balls should behave in a more manageable way, see: #46622. */ uv[0] = uv[1] = 0.0f; @@ -5470,7 +5470,7 @@ void BKE_particle_system_blend_read_lib(BlendLibReader *reader, BLO_read_id_address(reader, id->lib, &psys->target_ob); if (psys->clmd) { - /* XXX(@campbellbarton): from reading existing code this seems correct but intended usage + /* XXX(@ideasman42): from reading existing code this seems correct but intended usage * of point-cache with cloth should be added in #ParticleSystem. */ psys->clmd->point_cache = psys->pointcache; psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = nullptr; diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 085f2cc8ddb..671a3e17cdf 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -1206,12 +1206,12 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, step = (totpart < 2) ? 0.5 : 1.0 / (double)totpart; /* This is to address tricky issues with vertex-emitting when user tries - * (and expects) exact 1-1 vert/part distribution (see T47983 and its two example files). + * (and expects) exact 1-1 vert/part distribution (see #47983 and its two example files). * It allows us to consider pos as 'midpoint between v and v+1' * (or 'p and p+1', depending whether we have more vertices than particles or not), * and avoid stumbling over float impression in element_sum. * NOTE: moved face and volume distribution to this as well (instead of starting at zero), - * for the same reasons, see T52682. */ + * for the same reasons, see #52682. */ pos = (totpart < totmapped) ? 0.5 / (double)totmapped : step * 0.5; /* We choose the smaller step. */ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 25935a590b9..1053bfaf875 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -590,7 +590,7 @@ static void initialize_all_particles(ParticleSimulationData *sim) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - /* Grid distributionsets UNEXIST flag, need to take care of + /* Grid distribution-sets UNEXIST flag, need to take care of * it here because later this flag is being reset. * * We can't do it for any distribution, because it'll then @@ -967,7 +967,7 @@ void psys_get_birth_coords( float tmat[3][3]; /* NOTE: utan_local is not taken from 'utan', we calculate from rot_vec/vtan. */ - /* NOTE(@campbellbarton): it looks like rotation phase may be applied twice + /* NOTE(@ideasman42): it looks like rotation phase may be applied twice * (once with vtan, again below) however this isn't the case. */ float *rot_vec_local = tmat[0]; float *vtan_local = tmat[1]; @@ -1931,7 +1931,7 @@ static void sphclassical_density_accum_cb(void *userdata, return; } - /* Smoothing factor. Utilize the Wendland kernel. gnuplot: + /* Smoothing factor. Utilize the Wendland kernel. `gnuplot`: * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x) * plot [0:2] q1(x) */ q = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * (1.0f + 2.0f * rij_h); @@ -2021,7 +2021,7 @@ static void sphclassical_force_cb(void *sphdata_v, NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbor_accum_cb); pressure = stiffness * (pow7f(pa->sphdensity / rest_density) - 1.0f); - /* multiply by mass so that we return a force, not accel */ + /* Multiply by mass so that we return a force, not acceleration. */ qfac2 *= sphdata->mass / pow3f(pfr.h); pfn = pfr.neighbors; @@ -2047,7 +2047,7 @@ static void sphclassical_force_cb(void *sphdata_v, npressure = stiffness * (pow7f(npa->sphdensity / rest_density) - 1.0f); /* First derivative of smoothing factor. Utilize the Wendland kernel. - * gnuplot: + * `gnuplot`: * q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x) * plot [0:2] q2(x) * Particles > 2h away are excluded above. */ @@ -2438,15 +2438,17 @@ static float nr_distance_to_vert(float *p, { return len_v3v3(p, pce->x0) - radius; } +/** + * \param t: is the current time for newton rhapson. + * \param fac: is the starting factor for current collision iteration. + * \param col: The particle collision, `col->fac's` are factors for the + * particle sub-frame step start and end during collision modifier step. + */ static void collision_interpolate_element(ParticleCollisionElement *pce, float t, float fac, ParticleCollision *col) { - /* t is the current time for newton rhapson */ - /* fac is the starting factor for current collision iteration */ - /* The col->fac's are factors for the particle subframe step start - * and end during collision modifier step. */ float f = fac + t * (1.0f - fac); float mul = col->fac1 + f * (col->fac2 - col->fac1); if (pce->tot > 0) { @@ -3534,12 +3536,12 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re } } - /* dynamics with cloth simulation, psys->particles can be NULL with 0 particles T25519. */ + /* dynamics with cloth simulation, psys->particles can be NULL with 0 particles #25519. */ if (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS && psys->particles) { do_hair_dynamics(sim); } - /* following lines were removed r29079 but cause bug T22811, see report for details */ + /* following lines were removed r29079 but cause bug #22811, see report for details */ psys_update_effectors(sim); psys_update_path_cache(sim, cfra, use_render_params); @@ -3598,19 +3600,21 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) psys_sim_data_free(sim); } -/* Code for an adaptive time step based on the Courant-Friedrichs-Lewy - * condition. */ +/** Code for an adaptive time step based on the Courant-Friedrichs-Lewy condition. */ static const float MIN_TIMESTEP = 1.0f / 101.0f; -/* Tolerance of 1.5 means the last subframe neither favors growing nor - * shrinking (e.g if it were 1.3, the last subframe would tend to be too - * small). */ +/** + * Tolerance of 1.5 means the last sub-frame neither favors growing nor shrinking + * (e.g if it were 1.3, the last sub-frame would tend to be too small). + */ static const float TIMESTEP_EXPANSION_FACTOR = 0.1f; static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f; -/* Calculate the speed of the particle relative to the local scale of the +/** + * Calculate the speed of the particle relative to the local scale of the * simulation. This should be called once per particle during a simulation * step, after the velocity has been updated. element_size defines the scale of - * the simulation, and is typically the distance to neighboring particles. */ + * the simulation, and is typically the distance to neighboring particles. + */ static void update_courant_num( ParticleSimulationData *sim, ParticleData *pa, float dtime, SPHData *sphdata, SpinLock *spin) { diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 7c829d32a82..7d4769c6e25 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -932,7 +932,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh, /* Ensure leaf limit is at least 4 so there's room * to split at original face boundaries. - * Fixes T102209. + * Fixes #102209. */ pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), max_grids); diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.cc b/source/blender/blenkernel/intern/pbvh_bmesh.cc index fcccfc384fa..b5f5a3b7ce1 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.cc +++ b/source/blender/blenkernel/intern/pbvh_bmesh.cc @@ -738,7 +738,7 @@ struct EdgeQueueContext { /* Only tagged edges are in the queue. */ #ifdef USE_EDGEQUEUE_TAG -# define EDGE_QUEUE_TEST(e) (BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)) +# define EDGE_QUEUE_TEST(e) BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG) # define EDGE_QUEUE_ENABLE(e) \ BM_elem_flag_enable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG) # define EDGE_QUEUE_DISABLE(e) \ @@ -1417,7 +1417,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh, normalize_v3(v_conn->no); /* Update bounding boxes attached to the connected vertex. - * Note that we can often get-away without this but causes T48779. */ + * Note that we can often get-away without this but causes #48779. */ BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) { PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, l->f); f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateBB; diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 279ce42c405..a8f9d76b9db 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -49,7 +49,7 @@ static int primitive_get_other_uv_vertex(const MeshData &mesh_data, mesh_loops[looptri.tri[2]].v)); for (const int loop : looptri.tri) { const int vert = mesh_loops[loop].v; - if (vert != v1 && vert != v2) { + if (!ELEM(vert, v1, v2)) { return vert; } } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 5622530ea41..1a75f34a826 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -3133,10 +3133,10 @@ static void ptcache_dt_to_str(char *str, double dtime) if (dtime > 60.0) { if (dtime > 3600.0) { BLI_sprintf( - str, "%ih %im %is", (int)(dtime / 3600), ((int)(dtime / 60)) % 60, ((int)dtime) % 60); + str, "%ih %im %is", (int)(dtime / 3600), (int)(dtime / 60) % 60, ((int)dtime) % 60); } else { - BLI_sprintf(str, "%im %is", ((int)(dtime / 60)) % 60, ((int)dtime) % 60); + BLI_sprintf(str, "%im %is", (int)(dtime / 60) % 60, ((int)dtime) % 60); } } else { diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 6f9abd4c48d..90169a94ebd 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1728,7 +1728,7 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, { /* update world */ /* Note physics_world can get NULL when undoing the deletion of the last object in it (see - * T70667). */ + * #70667). */ if (rebuild || rbw->shared->physics_world == NULL) { BKE_rigidbody_validate_sim_world(scene, rbw, rebuild); /* We have rebuilt the world so we need to make sure the rest is rebuilt as well. */ diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 445a1517965..ccf62a6f899 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -2588,7 +2588,7 @@ static bool check_rendered_viewport_visible(Main *bmain) return false; } -/* TODO(@campbellbarton): shouldn't we be able to use 'DEG_get_view_layer' here? +/* TODO(@ideasman42): shouldn't we be able to use 'DEG_get_view_layer' here? * Currently this is nullptr on load, so don't. */ static void prepare_mesh_for_viewport_render(Main *bmain, const Scene *scene, @@ -3083,7 +3083,7 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl return value * pow(unit->scale_length, 3); case B_UNIT_MASS: return value * pow(unit->scale_length, 3); - case B_UNIT_CAMERA: /* *Do not* use scene's unit scale for camera focal lens! See T42026. */ + case B_UNIT_CAMERA: /* *Do not* use scene's unit scale for camera focal lens! See #42026. */ default: return value; } diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index f6fab916426..96e4fb941af 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -854,7 +854,7 @@ static double get_cur_time(Scene *scene) { /* We divide by the current framelen to take into account time remapping. * Otherwise we will get the wrong starting time which will break A/V sync. - * See T74111 for further details. */ + * See #74111 for further details. */ return FRA2TIME((scene->r.cfra + scene->r.subframe) / (double)scene->r.framelen); } @@ -1230,7 +1230,7 @@ bool BKE_sound_info_get(struct Main *main, struct bSound *sound, SoundInfo *soun } /* TODO(sergey): Make it fully independent audio handle. */ /* Don't free waveforms during non-destructive queries. - * This causes unnecessary recalculation - see T69921 */ + * This causes unnecessary recalculation - see #69921 */ sound_load_audio(main, sound, false); const bool result = sound_info_from_playback_handle(sound->playback_handle, sound_info); sound_free_audio(sound); diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index 0f735f06b42..ee9e02883c6 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -536,6 +536,10 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices); subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.clear(); subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.resize(num_vertices); + if (subdiv_context->settings->use_optimal_display) { + subdiv_context->subdiv_mesh->runtime->subsurf_optimal_display_edges.clear(); + subdiv_context->subdiv_mesh->runtime->subsurf_optimal_display_edges.resize(num_edges); + } return true; } @@ -784,15 +788,10 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context * \{ */ static void subdiv_copy_edge_data(SubdivMeshContext *ctx, - MEdge *subdiv_edge, + const int subdiv_edge_index, const int coarse_edge_index) { - const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges; if (coarse_edge_index == ORIGINDEX_NONE) { - subdiv_edge->flag = 0; - if (!ctx->settings->use_optimal_display) { - subdiv_edge->flag |= ME_EDGEDRAW; - } if (ctx->edge_origindex != nullptr) { ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE; } @@ -800,7 +799,9 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx, } CustomData_copy_data( &ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1); - subdiv_edge->flag |= ME_EDGEDRAW; + if (ctx->settings->use_optimal_display) { + ctx->subdiv_mesh->runtime->subsurf_optimal_display_edges[subdiv_edge_index].set(); + } } static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context, @@ -814,7 +815,7 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context, SubdivMeshContext *ctx = static_cast(foreach_context->user_data); MEdge *subdiv_medge = ctx->subdiv_edges; MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index]; - subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge_index); + subdiv_copy_edge_data(ctx, subdiv_edge_index, coarse_edge_index); subdiv_edge->v1 = subdiv_v1; subdiv_edge->v2 = subdiv_v2; } diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 3221e43d4e6..60d55af215c 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -49,6 +49,8 @@ bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_ * was already allocated. */ if (runtime_data) { runtime_data->settings = settings; + + runtime_data->used_cpu = runtime_data->used_gpu = 0; } return false; @@ -162,15 +164,18 @@ Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtim const Mesh *mesh, const bool for_draw_code) { - if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) { - BKE_subdiv_free(runtime_data->subdiv); - runtime_data->subdiv = nullptr; + if (for_draw_code) { + runtime_data->used_gpu = 2; /* countdown in frames */ + + return runtime_data->subdiv_gpu = BKE_subdiv_update_from_mesh( + runtime_data->subdiv_gpu, &runtime_data->settings, mesh); + } + else { + runtime_data->used_cpu = 2; + + return runtime_data->subdiv_cpu = BKE_subdiv_update_from_mesh( + runtime_data->subdiv_cpu, &runtime_data->settings, mesh); } - Subdiv *subdiv = BKE_subdiv_update_from_mesh( - runtime_data->subdiv, &runtime_data->settings, mesh); - runtime_data->subdiv = subdiv; - runtime_data->set_by_draw_code = for_draw_code; - return subdiv; } int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index abeb0f33a18..47e2ecf98e8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -269,7 +269,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, limit[0] = limit[1] = STD_UV_CONNECT_LIMIT; /* previous behavior here is without accounting for winding, however this causes stretching in - * UV map in really simple cases with mirror + subsurf, see second part of T44530. + * UV map in really simple cases with mirror + subsurf, see second part of #44530. * Also, initially intention is to treat merged vertices from mirror modifier as seams. * This fixes a very old regression (2.49 was correct here) */ vmap = BKE_mesh_uv_vert_map_create( @@ -893,7 +893,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3]) int x; for (x = 1; x < edgeSize - 1; x++) { - /* NOTE(@campbellbarton): This gives errors with `--debug-fpe` the normals don't seem to be + /* NOTE(@ideasman42): This gives errors with `--debug-fpe` the normals don't seem to be * unit length. This is most likely caused by edges with no faces which are now zeroed out, * see comment in: `ccgSubSurf__calcVertNormals()`. */ vd = static_cast(ccgSubSurf_getEdgeData(ss, e, x)); @@ -928,7 +928,6 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) int edgeSize = ccgSubSurf_getEdgeSize(ss); uint i = 0; short *edgeFlags = ccgdm->edgeFlags; - const short ed_interior_flag = ccgdm->drawInteriorEdges ? ME_EDGEDRAW : 0; totface = ccgSubSurf_getNumFaces(ss); for (index = 0; index < totface; index++) { @@ -940,7 +939,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) ccgDM_to_MEdge(&medge[i++], getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize), getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize), - ed_interior_flag); + 0); } for (x = 1; x < gridSize - 1; x++) { @@ -948,11 +947,11 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) ccgDM_to_MEdge(&medge[i++], getFaceIndex(ss, f, S, x, y, edgeSize, gridSize), getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize), - ed_interior_flag); + 0); ccgDM_to_MEdge(&medge[i++], getFaceIndex(ss, f, S, y, x, edgeSize, gridSize), getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize), - ed_interior_flag); + 0); } } } @@ -967,12 +966,9 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) if (edgeFlags) { if (edgeIdx != -1) { - ed_flag |= ((edgeFlags[index] & ME_SEAM) | ME_EDGEDRAW); + ed_flag |= (edgeFlags[index] & ME_SEAM); } } - else { - ed_flag |= ME_EDGEDRAW; - } for (x = 0; x < edgeSize - 1; x++) { ccgDM_to_MEdge(&medge[i++], @@ -1367,7 +1363,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) gridFlagMats = static_cast( MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats")); - ccgdm->gridHidden = static_cast( + ccgdm->gridHidden = static_cast( MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden")); for (gIndex = 0, index = 0; index < numFaces; index++) { @@ -1889,7 +1885,7 @@ DerivedMesh *subsurf_make_derived_from_derived(DerivedMesh *dm, CCGDerivedMesh *result; /* NOTE: editmode calculation can only run once per - * modifier stack evaluation (uses freed cache) T36299. */ + * modifier stack evaluation (uses freed cache) #36299. */ if (flags & SUBSURF_FOR_EDIT_MODE) { int levels = (scene != nullptr && !ignore_simplify) ? get_render_subsurf_level(&scene->r, smd->levels, false) : diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 1a0c0716fcd..9b2f9c72c90 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -392,7 +392,7 @@ static void text_from_buf(Text *text, const uchar *buffer, const int len) * in this case content of such line would be used to fill text line buffer * - file is empty. in this case new line is needed to start editing from. * - last character in buffer is \n. in this case new line is needed to - * deal with newline at end of file. (see T28087) (sergey) */ + * deal with newline at end of file. (see #28087) (sergey) */ if (llen != 0 || lines_count == 0 || buffer[len - 1] == '\n') { TextLine *tmp; @@ -2225,7 +2225,7 @@ int txt_setcurr_tab_spaces(Text *text, int space) /* if we find a ':' on this line, then add a tab but not if it is: * 1) in a comment * 2) within an identifier - * 3) after the cursor (text->curc), i.e. when creating space before a function def T25414. + * 3) after the cursor (text->curc), i.e. when creating space before a function def #25414. */ int a; bool is_indent = false; diff --git a/source/blender/blenkernel/intern/undo_system.cc b/source/blender/blenkernel/intern/undo_system.cc index 946d94f1503..01235e718f3 100644 --- a/source/blender/blenkernel/intern/undo_system.cc +++ b/source/blender/blenkernel/intern/undo_system.cc @@ -40,7 +40,7 @@ #define WITH_GLOBAL_UNDO_ENSURE_UPDATED /** - * Make sure we don't apply edits on top of a newer memfile state, see: T56163. + * Make sure we don't apply edits on top of a newer memfile state, see: #56163. * \note Keep an eye on this, could solve differently. */ #define WITH_GLOBAL_UNDO_CORRECT_ORDER @@ -183,7 +183,7 @@ static void undosys_step_decode(bContext *C, } else { /* Load the previous memfile state so any ID's referenced in this - * undo step will be correctly resolved, see: T56163. */ + * undo step will be correctly resolved, see: #56163. */ undosys_step_decode(C, bmain, ustack, us_iter, dir, false); /* May have been freed on memfile read. */ bmain = G_MAIN; @@ -564,7 +564,7 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, if (use_memfile_step) { /* Make this the user visible undo state, so redo always applies - * on top of the mem-file undo instead of skipping it. see: T67256. */ + * on top of the mem-file undo instead of skipping it. see: #67256. */ UndoStep *us_prev = ustack->step_active; const char *name_internal = us_prev->name; const bool ok = undosys_stack_push_main(ustack, name_internal, G_MAIN); diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index 9f48b9b9c4a..5c468689e94 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -720,10 +720,10 @@ typedef struct VFontToCurveIter { * Wrap words that extends beyond the text-box width (enabled by default). * * Currently only disabled when scale-to-fit is enabled, - * so floating-point error doesn't cause unexpected wrapping, see T89241. + * so floating-point error doesn't cause unexpected wrapping, see #89241. * * \note This should only be set once, in the #VFONT_TO_CURVE_INIT pass - * otherwise iterations wont behave predictably, see T91401. + * otherwise iterations wont behave predictably, see #91401. */ bool word_wrap; int status; @@ -974,7 +974,7 @@ static bool vfont_to_curve(Object *ob, * * Floating precision error can cause the text to be slightly larger. * Assert this is a small value as large values indicate incorrect - * calculations with scale-to-fit which shouldn't be ignored. See T89241. */ + * calculations with scale-to-fit which shouldn't be ignored. See #89241. */ if (x_used > x_available) { BLI_assert_msg(compare_ff_relative(x_used, x_available, FLT_EPSILON, 64), "VFontToCurveIter.scale_to_fit not set correctly!"); @@ -993,7 +993,7 @@ static bool vfont_to_curve(Object *ob, * Typically when a text-box has any height and overflow is set to scale * the text will wrap to fit the width as necessary. When wrapping isn't * possible it's important to use the same code-path as zero-height lines. - * Without this exception a single word will not scale-to-fit (see: T95116). */ + * Without this exception a single word will not scale-to-fit (see: #95116). */ tb_scale.h = 0.0f; } break; @@ -1229,7 +1229,7 @@ static bool vfont_to_curve(Object *ob, if (cu->overflow == CU_OVERFLOW_TRUNCATE) { /* Ensure overflow doesn't truncate text, before centering vertically - * giving odd/buggy results, see: T66614. */ + * giving odd/buggy results, see: #66614. */ if ((tb_index == cu->totbox - 1) && (last_line != -1)) { lines = last_line - ct_first->linenr; } diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index 8fb8f40cbcc..8cb59a310b6 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -99,7 +99,7 @@ struct VolumeToMeshOp { openvdb::tools::volumeToMesh( grid, this->verts, this->tris, this->quads, this->threshold, this->adaptivity); - /* Better align generated mesh with volume (see T85312). */ + /* Better align generated mesh with volume (see #85312). */ openvdb::Vec3s offset = grid.voxelSize() / 2.0f; for (openvdb::Vec3s &position : this->verts) { position += offset; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index be8f985ec56..6d5bacdb2d2 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -477,7 +477,7 @@ static const AVCodec *get_av1_encoder( switch (context->ffmpeg_preset) { case FFM_PRESET_BEST: /* `libaom-av1` may produce better VMAF-scoring videos in several cases, but there are cases - * where using a different encoder is desirable, such as in T103849. */ + * where using a different encoder is desirable, such as in #103849. */ codec = avcodec_find_encoder_by_name("librav1e"); if (!codec) { /* Fallback to `libaom-av1` if librav1e is not found. */ @@ -527,7 +527,7 @@ static const AVCodec *get_av1_encoder( if (context->ffmpeg_crf >= 0) { /* librav1e does not use `-crf`, but uses `-qp` in the range of 0-255. * Calculates the roughly equivalent float, and truncates it to an integer. */ - unsigned int qp_value = ((float)context->ffmpeg_crf) * 255.0F / 51.0F; + uint qp_value = ((float)context->ffmpeg_crf) * 255.0f / 51.0f; if (qp_value > 255) { qp_value = 255; } @@ -1666,7 +1666,7 @@ void BKE_ffmpeg_preset_set(RenderData *rd, int preset) rd->ffcodecdata.type = FFMPEG_MPEG2; rd->ffcodecdata.video_bitrate = 6000; -# if 0 /* Don't set resolution, see T21351. */ +# if 0 /* Don't set resolution, see #21351. */ rd->xsch = 720; rd->ysch = isntsc ? 480 : 576; # endif diff --git a/source/blender/blenlib/BLI_bit_vector.hh b/source/blender/blenlib/BLI_bit_vector.hh index bad371fc88a..237bdce1452 100644 --- a/source/blender/blenlib/BLI_bit_vector.hh +++ b/source/blender/blenlib/BLI_bit_vector.hh @@ -16,13 +16,13 @@ * * The compact nature of storing bools in individual bits has some downsides that have to be kept * in mind: - * - Writing to separate bits in the same byte is not thread-safe. Therefore, an existing vector of + * - Writing to separate bits in the same int is not thread-safe. Therefore, an existing vector of * bool can't easily be replaced with a bit vector, if it is written to from multiple threads. * Read-only access from multiple threads is fine though. * - Writing individual elements is more expensive when the array is in cache already. That is - * because changing a bit is always a read-modify-write operation on the byte the bit resides in. + * because changing a bit is always a read-modify-write operation on the int the bit resides in. * - Reading individual elements is more expensive when the array is in cache already. That is - * because additional bit-wise operations have to be applied after the corresponding byte is + * because additional bit-wise operations have to be applied after the corresponding int is * read. * * Comparison to `std::vector`: @@ -42,18 +42,27 @@ #include "BLI_memory_utils.hh" #include "BLI_span.hh" -namespace blender { +namespace blender::bits { /** - * This is a read-only pointer to a specific bit. The value of the bit can be retrieved, but not - * changed. + * Using a large integer type is better because then it's easier to process many bits at once. + */ +using IntType = uint64_t; +static constexpr int64_t BitsPerInt = int64_t(sizeof(IntType) * 8); +static constexpr int64_t BitToIntIndexShift = 3 + (sizeof(IntType) >= 2) + (sizeof(IntType) >= 4) + + (sizeof(IntType) >= 8); +static constexpr IntType BitIndexMask = (IntType(1) << BitToIntIndexShift) - 1; + +/** + * This is a read-only pointer to a specific bit. The value of the bit can be retrieved, but + * not changed. */ class BitRef { private: - /** Points to the exact byte that the bit is in. */ - const uint8_t *byte_ptr_; + /** Points to the integer that the bit is in. */ + const IntType *ptr_; /** All zeros except for a single one at the bit that is referenced. */ - uint8_t mask_; + IntType mask_; friend class MutableBitRef; @@ -61,13 +70,13 @@ class BitRef { BitRef() = default; /** - * Reference a specific bit in a byte array. Note that #byte_ptr does *not* have to point to the - * exact byte the bit is in. + * Reference a specific bit in an array. Note that #ptr does *not* have to point to the + * exact integer the bit is in. */ - BitRef(const uint8_t *byte_ptr, const int64_t bit_index) + BitRef(const IntType *ptr, const int64_t bit_index) { - byte_ptr_ = byte_ptr + (bit_index >> 3); - mask_ = 1 << (bit_index & 7); + ptr_ = ptr + (bit_index >> BitToIntIndexShift); + mask_ = IntType(1) << (bit_index & BitIndexMask); } /** @@ -75,9 +84,9 @@ class BitRef { */ bool test() const { - const uint8_t byte = *byte_ptr_; - const uint8_t masked_byte = byte & mask_; - return masked_byte != 0; + const IntType value = *ptr_; + const IntType masked_value = value & mask_; + return masked_value != 0; } operator bool() const @@ -91,22 +100,22 @@ class BitRef { */ class MutableBitRef { private: - /** Points to the exact byte that the bit is in. */ - uint8_t *byte_ptr_; + /** Points to the integer that the bit is in. */ + IntType *ptr_; /** All zeros except for a single one at the bit that is referenced. */ - uint8_t mask_; + IntType mask_; public: MutableBitRef() = default; /** - * Reference a specific bit in a byte array. Note that #byte_ptr does *not* have to point to the - * exact byte the bit is in. + * Reference a specific bit in an array. Note that #ptr does *not* have to point to the + * exact int the bit is in. */ - MutableBitRef(uint8_t *byte_ptr, const int64_t bit_index) + MutableBitRef(IntType *ptr, const int64_t bit_index) { - byte_ptr_ = byte_ptr + (bit_index >> 3); - mask_ = 1 << uint8_t(bit_index & 7); + ptr_ = ptr + (bit_index >> BitToIntIndexShift); + mask_ = IntType(1) << IntType(bit_index & BitIndexMask); } /** @@ -115,7 +124,7 @@ class MutableBitRef { operator BitRef() const { BitRef bit_ref; - bit_ref.byte_ptr_ = byte_ptr_; + bit_ref.ptr_ = ptr_; bit_ref.mask_ = mask_; return bit_ref; } @@ -125,9 +134,9 @@ class MutableBitRef { */ bool test() const { - const uint8_t byte = *byte_ptr_; - const uint8_t masked_byte = byte & mask_; - return masked_byte != 0; + const IntType value = *ptr_; + const IntType masked_value = value & mask_; + return masked_value != 0; } operator bool() const @@ -140,7 +149,7 @@ class MutableBitRef { */ void set() { - *byte_ptr_ |= mask_; + *ptr_ |= mask_; } /** @@ -148,7 +157,7 @@ class MutableBitRef { */ void reset() { - *byte_ptr_ &= ~mask_; + *ptr_ &= ~mask_; } /** @@ -177,21 +186,20 @@ template< typename Allocator = GuardedAllocator> class BitVector { private: - static constexpr int64_t required_bytes_for_bits(const int64_t number_of_bits) + static constexpr int64_t required_ints_for_bits(const int64_t number_of_bits) { - return (number_of_bits + BitsPerByte - 1) / BitsPerByte; + return (number_of_bits + BitsPerInt - 1) / BitsPerInt; } - static constexpr int64_t BitsPerByte = 8; - static constexpr int64_t BytesInInlineBuffer = required_bytes_for_bits(InlineBufferCapacity); - static constexpr int64_t BitsInInlineBuffer = BytesInInlineBuffer * BitsPerByte; - static constexpr int64_t AllocationAlignment = 8; + static constexpr int64_t IntsInInlineBuffer = required_ints_for_bits(InlineBufferCapacity); + static constexpr int64_t BitsInInlineBuffer = IntsInInlineBuffer * BitsPerInt; + static constexpr int64_t AllocationAlignment = alignof(IntType); /** - * Points to the first byte used by the vector. It might point to the memory in the inline + * Points to the first integer used by the vector. It might point to the memory in the inline * buffer. */ - uint8_t *data_; + IntType *data_; /** Current size of the vector in bits. */ int64_t size_in_bits_; @@ -203,7 +211,7 @@ class BitVector { BLI_NO_UNIQUE_ADDRESS Allocator allocator_; /** Contains the bits as long as the vector is small enough. */ - BLI_NO_UNIQUE_ADDRESS TypedBuffer inline_buffer_; + BLI_NO_UNIQUE_ADDRESS TypedBuffer inline_buffer_; public: BitVector(Allocator allocator = {}) noexcept : allocator_(allocator) @@ -211,7 +219,7 @@ class BitVector { data_ = inline_buffer_; size_in_bits_ = 0; capacity_in_bits_ = BitsInInlineBuffer; - uninitialized_fill_n(data_, BytesInInlineBuffer, uint8_t(0)); + uninitialized_fill_n(data_, IntsInInlineBuffer, IntType(0)); } BitVector(NoExceptConstructor, Allocator allocator = {}) noexcept : BitVector(allocator) @@ -220,29 +228,29 @@ class BitVector { BitVector(const BitVector &other) : BitVector(NoExceptConstructor(), other.allocator_) { - const int64_t bytes_to_copy = other.used_bytes_amount(); + const int64_t ints_to_copy = other.used_ints_amount(); if (other.size_in_bits_ <= BitsInInlineBuffer) { /* The data is copied into the owned inline buffer. */ data_ = inline_buffer_; capacity_in_bits_ = BitsInInlineBuffer; } else { - /* Allocate a new byte array because the inline buffer is too small. */ - data_ = static_cast( - allocator_.allocate(bytes_to_copy, AllocationAlignment, __func__)); - capacity_in_bits_ = bytes_to_copy * BitsPerByte; + /* Allocate a new array because the inline buffer is too small. */ + data_ = static_cast( + allocator_.allocate(ints_to_copy * sizeof(IntType), AllocationAlignment, __func__)); + capacity_in_bits_ = ints_to_copy * BitsPerInt; } size_in_bits_ = other.size_in_bits_; - uninitialized_copy_n(other.data_, bytes_to_copy, data_); + uninitialized_copy_n(other.data_, ints_to_copy, data_); } BitVector(BitVector &&other) noexcept : BitVector(NoExceptConstructor(), other.allocator_) { if (other.is_inline()) { /* Copy the data into the inline buffer. */ - const int64_t bytes_to_copy = other.used_bytes_amount(); + const int64_t ints_to_copy = other.used_ints_amount(); data_ = inline_buffer_; - uninitialized_copy_n(other.data_, bytes_to_copy, data_); + uninitialized_copy_n(other.data_, ints_to_copy, data_); } else { /* Steal the pointer. */ @@ -305,7 +313,7 @@ class BitVector { bool is_empty() const { - return this->size() == 0; + return size_in_bits_ == 0; } /** @@ -442,20 +450,20 @@ class BitVector { */ void fill_range(const IndexRange range, const bool value) { - const AlignedIndexRanges aligned_ranges = split_index_range_by_alignment(range, BitsPerByte); + const AlignedIndexRanges aligned_ranges = split_index_range_by_alignment(range, BitsPerInt); /* Fill first few bits. */ for (const int64_t i : aligned_ranges.prefix) { (*this)[i].set(value); } - /* Fill entire bytes at once. */ - const int64_t start_fill_byte_index = aligned_ranges.aligned.start() / BitsPerByte; - const int64_t bytes_to_fill = aligned_ranges.aligned.size() / BitsPerByte; - const uint8_t fill_value = value ? uint8_t(0xff) : uint8_t(0x00); - initialized_fill_n(data_ + start_fill_byte_index, bytes_to_fill, fill_value); + /* Fill entire ints at once. */ + const int64_t start_fill_int_index = aligned_ranges.aligned.start() / BitsPerInt; + const int64_t ints_to_fill = aligned_ranges.aligned.size() / BitsPerInt; + const IntType fill_value = value ? IntType(-1) : IntType(0); + initialized_fill_n(data_ + start_fill_int_index, ints_to_fill, fill_value); - /* Fill bits in the end that don't cover a full byte. */ + /* Fill bits in the end that don't cover a full int. */ for (const int64_t i : aligned_ranges.suffix) { (*this)[i].set(value); } @@ -509,37 +517,35 @@ class BitVector { } BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity_in_bits, - const uint8_t initial_value_for_new_bytes = 0x00) + const IntType initial_value_for_new_ints = 0x00) { if (capacity_in_bits_ >= min_capacity_in_bits) { return; } - const int64_t min_capacity_in_bytes = this->required_bytes_for_bits(min_capacity_in_bits); + const int64_t min_capacity_in_ints = this->required_ints_for_bits(min_capacity_in_bits); /* At least double the size of the previous allocation. */ - const int64_t min_new_capacity_in_bytes = capacity_in_bits_ * 2; + const int64_t min_new_capacity_in_ints = 2 * this->required_ints_for_bits(capacity_in_bits_); - const int64_t new_capacity_in_bytes = std::max(min_capacity_in_bytes, - min_new_capacity_in_bytes); - const int64_t bytes_to_copy = this->used_bytes_amount(); + const int64_t new_capacity_in_ints = std::max(min_capacity_in_ints, min_new_capacity_in_ints); + const int64_t ints_to_copy = this->used_ints_amount(); - uint8_t *new_data = static_cast( - allocator_.allocate(new_capacity_in_bytes, AllocationAlignment, __func__)); - uninitialized_copy_n(data_, bytes_to_copy, new_data); + IntType *new_data = static_cast(allocator_.allocate( + new_capacity_in_ints * sizeof(IntType), AllocationAlignment, __func__)); + uninitialized_copy_n(data_, ints_to_copy, new_data); /* Always initialize new capacity even if it isn't used yet. That's necessary to avoid warnings * caused by using uninitialized memory. This happens when e.g. setting a clearing a bit in an - * uninitialized byte. */ - uninitialized_fill_n(new_data + bytes_to_copy, - new_capacity_in_bytes - bytes_to_copy, - uint8_t(initial_value_for_new_bytes)); + * uninitialized int. */ + uninitialized_fill_n( + new_data + ints_to_copy, new_capacity_in_ints - ints_to_copy, initial_value_for_new_ints); if (!this->is_inline()) { allocator_.deallocate(data_); } data_ = new_data; - capacity_in_bits_ = new_capacity_in_bytes * BitsPerByte; + capacity_in_bits_ = new_capacity_in_ints * BitsPerInt; } bool is_inline() const @@ -547,10 +553,16 @@ class BitVector { return data_ == inline_buffer_; } - int64_t used_bytes_amount() const + int64_t used_ints_amount() const { - return this->required_bytes_for_bits(size_in_bits_); + return this->required_ints_for_bits(size_in_bits_); } }; +} // namespace blender::bits + +namespace blender { +using bits::BitRef; +using bits::BitVector; +using bits::MutableBitRef; } // namespace blender diff --git a/source/blender/blenlib/BLI_index_mask_ops.hh b/source/blender/blenlib/BLI_index_mask_ops.hh index e4eece11e83..51c80bafe3e 100644 --- a/source/blender/blenlib/BLI_index_mask_ops.hh +++ b/source/blender/blenlib/BLI_index_mask_ops.hh @@ -71,4 +71,9 @@ IndexMask find_indices_from_virtual_array(IndexMask indices_to_check, int64_t parallel_grain_size, Vector &r_indices); +/** + * Find the true indices in a boolean span. + */ +IndexMask find_indices_from_array(Span array, Vector &r_indices); + } // namespace blender::index_mask_ops diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index c0c4594ddc0..eed379d02ad 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -97,8 +97,9 @@ MINLINE float saacos(float fac); MINLINE float saasin(float fac); MINLINE float sasqrt(float fac); -MINLINE float interpf(float a, float b, float t); -MINLINE double interpd(double a, double b, double t); +/* Compute linear interpolation (lerp) between origin and target. */ +MINLINE float interpf(float target, float origin, float t); +MINLINE double interpd(double target, double origin, double t); MINLINE float ratiof(float min, float max, float pos); MINLINE double ratiod(double min, double max, double pos); @@ -308,7 +309,7 @@ float ceil_power_of_10(float f); * check the vector is unit length, or zero length (which can't be helped in some cases). */ #ifndef NDEBUG -/** \note 0.0001 is too small because normals may be converted from short's: see T34322. */ +/** \note 0.0001 is too small because normals may be converted from short's: see #34322. */ # define BLI_ASSERT_UNIT_EPSILON 0.0002f # define BLI_ASSERT_UNIT_EPSILON_DB 0.0002 /** diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 1278bc90e44..5724f590aa3 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -246,7 +246,7 @@ bool invert_m4_m4(float inverse[4][4], const float mat[4][4]); * * \note this has worse performance than #EIG_invert_m4_m4 (Eigen), but e.g. * for non-invertible scale matrices, finding a partial solution can - * be useful to have a valid local transform center, see T57767. + * be useful to have a valid local transform center, see #57767. */ bool invert_m4_m4_fallback(float inverse[4][4], const float mat[4][4]); @@ -519,7 +519,7 @@ void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4] * (it typically remains below 2 usec on an average i74700, * while #blend_m3_m3m3 remains below 0.4 usec). * However, it gives expected results even with non-uniformly scaled matrices, - * see T46418 for an example. + * see #46418 for an example. * * Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff * diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index 31b3522c4aa..5b15920b136 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -94,7 +94,7 @@ template * (it typically remains below 2 usec on an average i74700, * while naive implementation remains below 0.4 usec). * However, it gives expected results even with non-uniformly scaled matrices, - * see T46418 for an example. + * see #46418 for an example. * * Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff * @@ -125,7 +125,7 @@ template * * \note This code is about five times faster than the polar decomposition. * However, it gives un-expected results even with non-uniformly scaled matrices, - * see T46418 for an example. + * see #46418 for an example. * * \param A: Input matrix which is totally effective with `t = 0.0`. * \param B: Input matrix which is totally effective with `t = 1.0`. @@ -142,7 +142,7 @@ template * * \note This code is about five times faster than the polar decomposition. * However, it gives un-expected results even with non-uniformly scaled matrices, - * see T46418 for an example. + * see #46418 for an example. * * \param A: Input matrix which is totally effective with `t = 0.0`. * \param B: Input matrix which is totally effective with `t = 1.0`. @@ -693,7 +693,7 @@ extern template void normalized_to_eul2(const double3x3 &mat, template detail::Quaternion normalized_to_quat_fast(const MatBase &mat) { BLI_assert(math::is_unit_scale(mat)); - /* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */ + /* Caller must ensure matrices aren't negative for valid results, see: #24291, #94231. */ BLI_assert(!math::is_negative(mat)); detail::Quaternion q; @@ -757,8 +757,8 @@ template detail::Quaternion normalized_to_quat_fast(const MatBase } } else { - /* NOTE(@campbellbarton): A zero matrix will fall through to this block, - * needed so a zero scaled matrices to return a quaternion without rotation, see: T101848. + /* NOTE(@ideasman42): A zero matrix will fall through to this block, + * needed so a zero scaled matrices to return a quaternion without rotation, see: #101848. */ const T trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2]; T s = 2.0f * math::sqrt(trace); diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index 992aba8a8b6..3646840c822 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -910,6 +910,27 @@ struct MutableMatView unroll([&](auto i) { (*this)[i] *= b; }); return *this; } + + /** Vector operators. Need to be redefined to avoid operator priority issue. */ + + friend col_type operator*(MutableMatView &a, const row_type &b) + { + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + col_type result(0); + unroll([&](auto c) { result += b[c] * a[c]; }); + return result; + } + + /** Multiply by the transposed. */ + friend row_type operator*(const col_type &a, MutableMatView &b) + { + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + row_type result(0); + unroll([&](auto c) { unroll([&](auto r) { result[c] += b[c][r] * a[r]; }); }); + return result; + } }; using float2x2 = MatBase; diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index cab5d16dd9b..6e1e04e65b2 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -252,6 +252,16 @@ template return result; } +template +[[nodiscard]] inline VecBase round(const VecBase &a) +{ + VecBase result; + for (int i = 0; i < Size; i++) { + result[i] = std::round(a[i]); + } + return result; +} + template [[nodiscard]] inline VecBase ceil(const VecBase &a) { diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 78f8e529740..3df5a85ca85 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -342,7 +342,7 @@ void BLI_path_normalize_dir(const char *relabase, char *dir, size_t dir_maxlen) * \note Space case ' ' is a bit of an edge case here - in theory it is allowed, * but again can be an issue in some cases, so we simply replace it by an underscore too * (good practice anyway). - * REMOVED based on popular demand (see T45900). + * REMOVED based on popular demand (see #45900). * Percent '%' char is a bit same case - not recommended to use it, * but supported by all decent file-systems/operating-systems around. * diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index b5b100ac27d..17d981be3b6 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -82,7 +82,7 @@ struct ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, struct ScanFillVert *v2); enum { - /* NOTE(@campbellbarton): using #BLI_SCANFILL_CALC_REMOVE_DOUBLES + /* NOTE(@ideasman42): using #BLI_SCANFILL_CALC_REMOVE_DOUBLES * Assumes ordered edges, otherwise we risk an eternal loop * removing double verts. */ BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1), diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h index cc5b5dce363..26355430f5c 100644 --- a/source/blender/blenlib/BLI_strict_flags.h +++ b/source/blender/blenlib/BLI_strict_flags.h @@ -9,7 +9,7 @@ */ #ifdef __GNUC__ -/* NOTE(@campbellbarton): CLANG behaves slightly differently to GCC, +/* NOTE(@ideasman42): CLANG behaves slightly differently to GCC, * these can be enabled but do so carefully as they can introduce build-errors. */ # if !defined(__clang__) # pragma GCC diagnostic error "-Wsign-compare" diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index 3be492009b0..b07e1f0a5bd 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -426,7 +426,7 @@ void BLI_task_graph_edge_create(struct TaskNode *from_node, struct TaskNode *to_ * cannot run the tasks itself. On a single thread, that causes a deadlock already. When there are * multiple threads, another thread will typically run the task and avoid the deadlock. However, if * this situation happens on all threads at the same time, all threads will deadlock. This happened - * in T88598. + * in #88598. * \{ */ void BLI_task_isolate(void (*func)(void *userdata), void *userdata); diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c index ac0c367785c..a263a8ec401 100644 --- a/source/blender/blenlib/intern/BLI_memiter.c +++ b/source/blender/blenlib/intern/BLI_memiter.c @@ -82,7 +82,7 @@ typedef struct BLI_memiter { BLI_INLINE uint data_offset_from_size(uint size) { - return (PADUP(size, (uint)sizeof(data_t))) / (uint)sizeof(data_t); + return PADUP(size, (uint)sizeof(data_t)) / (uint)sizeof(data_t); } static void memiter_set_rewind_offset(BLI_memiter *mi) diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 005de1f85b4..d7ab08d8bc8 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -526,7 +526,7 @@ int BLI_copy(const char *file, const char *to) # if 0 int BLI_create_symlink(const char *file, const char *to) { - /* See patch from T30870, should this ever become needed. */ + /* See patch from #30870, should this ever become needed. */ callLocalErrorCallBack("Linking files is unsupported on Windows"); (void)file; (void)to; diff --git a/source/blender/blenlib/intern/filereader_zstd.c b/source/blender/blenlib/intern/filereader_zstd.c index aeb000e9754..960be159c9d 100644 --- a/source/blender/blenlib/intern/filereader_zstd.c +++ b/source/blender/blenlib/intern/filereader_zstd.c @@ -281,7 +281,7 @@ static void zstd_close(FileReader *reader) if (zstd->reader.seek) { MEM_freeN(zstd->seek.uncompressed_ofs); MEM_freeN(zstd->seek.compressed_ofs); - /* When an error has occurred this may be NULL, see: T99744. */ + /* When an error has occurred this may be NULL, see: #99744. */ if (zstd->seek.cached_content) { MEM_freeN(zstd->seek.cached_content); } diff --git a/source/blender/blenlib/intern/index_mask.cc b/source/blender/blenlib/intern/index_mask.cc index adcc2de8bdb..bc58707b479 100644 --- a/source/blender/blenlib/intern/index_mask.cc +++ b/source/blender/blenlib/intern/index_mask.cc @@ -208,8 +208,7 @@ IndexMask find_indices_from_virtual_array(const IndexMask indices_to_check, } if (virtual_array.is_span()) { const Span span = virtual_array.get_internal_span(); - return find_indices_based_on_predicate( - indices_to_check, 4096, r_indices, [&](const int64_t i) { return span[i]; }); + return find_indices_from_array(span, r_indices); } threading::EnumerableThreadSpecific> materialize_buffers; @@ -241,4 +240,10 @@ IndexMask find_indices_from_virtual_array(const IndexMask indices_to_check, return detail::find_indices_based_on_predicate__merge(indices_to_check, sub_masks, r_indices); } +IndexMask find_indices_from_array(const Span array, Vector &r_indices) +{ + return find_indices_based_on_predicate( + array.index_range(), 4096, r_indices, [array](const int64_t i) { return array[i]; }); +} + } // namespace blender::index_mask_ops diff --git a/source/blender/blenlib/intern/kdtree_impl.h b/source/blender/blenlib/intern/kdtree_impl.h index f7993eb5adc..53a3ea90285 100644 --- a/source/blender/blenlib/intern/kdtree_impl.h +++ b/source/blender/blenlib/intern/kdtree_impl.h @@ -46,7 +46,7 @@ struct KDTree { /** * When set we know all values are unbalanced, - * otherwise clear them when re-balancing: see T62210. + * otherwise clear them when re-balancing: see #62210. */ #define KD_NODE_ROOT_IS_INIT ((uint)-2) diff --git a/source/blender/blenlib/intern/lazy_threading.cc b/source/blender/blenlib/intern/lazy_threading.cc index 4f6d3a75ecc..2185766dd57 100644 --- a/source/blender/blenlib/intern/lazy_threading.cc +++ b/source/blender/blenlib/intern/lazy_threading.cc @@ -12,7 +12,7 @@ namespace blender::lazy_threading { * deadlocks. */ using HintReceivers = RawStack, 0>, 0>; -thread_local HintReceivers hint_receivers = []() { +static thread_local HintReceivers hint_receivers = []() { HintReceivers receivers; /* Make sure there is always at least one vector. */ receivers.push_as(); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 415e21cd272..e55eb46235a 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1225,7 +1225,7 @@ int isect_seg_seg_v2_point_ex(const float v0[2], /* When 'd' approaches zero, float precision lets non-overlapping co-linear segments * detect as an intersection. So re-calculate 'v' to ensure the point overlaps both. - * see T45123 */ + * see #45123 */ /* inline since we have most vars already */ #if 0 @@ -1667,7 +1667,7 @@ bool isect_ray_tri_v3(const float ray_origin[3], float *r_lambda, float r_uv[2]) { - /* NOTE(@campbellbarton): these values were 0.000001 in 2.4x but for projection snapping on + /* NOTE(@ideasman42): these values were 0.000001 in 2.4x but for projection snapping on * a human head `(1BU == 1m)`, subdivision-surface level 2, this gave many errors. */ const float epsilon = 0.00000001f; float p[3], s[3], e1[3], e2[3], q[3]; @@ -2887,7 +2887,7 @@ int isect_line_line_epsilon_v3(const float v1[3], d = dot_v3v3(c, ab); div = dot_v3v3(ab, ab); - /* important not to use an epsilon here, see: T45919 */ + /* important not to use an epsilon here, see: #45919 */ /* test zero length line */ if (UNLIKELY(div == 0.0f)) { return 0; @@ -2962,7 +2962,7 @@ bool isect_line_line_strict_v3(const float v1[3], d = dot_v3v3(c, ab); div = dot_v3v3(ab, ab); - /* important not to use an epsilon here, see: T45919 */ + /* important not to use an epsilon here, see: #45919 */ /* test zero length line */ if (UNLIKELY(div == 0.0f)) { return false; @@ -3773,7 +3773,7 @@ void barycentric_weights_v2_quad(const float v1[2], const float co[2], float w[4]) { - /* NOTE(@campbellbarton): fabsf() here is not needed for convex quads + /* NOTE(@ideasman42): fabsf() here is not needed for convex quads * (and not used in #interp_weights_poly_v2). * But in the case of concave/bow-tie quads for the mask rasterizer it * gives unreliable results without adding `absf()`. If this becomes an issue for more general @@ -4034,7 +4034,7 @@ static float mean_value_half_tan_v3(const struct Float3_Len *d_curr, float cross[3]; cross_v3_v3v3(cross, d_curr->dir, d_next->dir); const float area = len_v3(cross); - /* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */ + /* Compare against zero since 'FLT_EPSILON' can be too large, see: #73348. */ if (LIKELY(area != 0.0f)) { const float dot = dot_v3v3(d_curr->dir, d_next->dir); const float len = d_curr->len * d_next->len; @@ -4060,7 +4060,7 @@ static double mean_value_half_tan_v2_db(const struct Double2_Len *d_curr, { /* Different from the 3d version but still correct. */ const double area = cross_v2v2_db(d_curr->dir, d_next->dir); - /* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */ + /* Compare against zero since 'FLT_EPSILON' can be too large, see: #73348. */ if (LIKELY(area != 0.0)) { const double dot = dot_v2v2_db(d_curr->dir, d_next->dir); const double len = d_curr->len * d_next->len; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index b8eaeb5c654..c74a0322ac5 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -257,7 +257,7 @@ void shuffle_m4(float R[4][4], const int index[4]) void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]) { - if (R == A || R == B) { + if (ELEM(R, A, B)) { float T[4][4]; mul_m4_m4m4(T, A, B); copy_m4_m4(R, T); @@ -359,7 +359,7 @@ void mul_m3_m3_post(float R[3][3], const float B[3][3]) void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]) { - if (R == A || R == B) { + if (ELEM(R, A, B)) { float T[3][3]; mul_m3_m3m3(T, A, B); copy_m3_m3(R, T); @@ -1663,7 +1663,7 @@ void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize) * * \note If an object has a zero scaled axis, this function can be used to "clean" the matrix * to behave as if the scale on that axis was `unit_length`. So it can be inverted - * or used in matrix multiply without creating degenerate matrices, see: T50103 + * or used in matrix multiply without creating degenerate matrices, see: #50103 * \{ */ /** @@ -2412,7 +2412,7 @@ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], con /* Quaternions cannot represent an axis flip. If such a singularity is detected, choose a * different decomposition of the matrix that still satisfies A = U_A * P_A but which has a - * positive determinant and thus no axis flips. This resolves T77154. + * positive determinant and thus no axis flips. This resolves #77154. * * Note that a flip of two axes is just a rotation of 180 degrees around the third axis, and * three flipped axes are just an 180 degree rotation + a single axis flip. It is thus sufficient diff --git a/source/blender/blenlib/intern/math_matrix.cc b/source/blender/blenlib/intern/math_matrix.cc index 122920923b2..f215b460001 100644 --- a/source/blender/blenlib/intern/math_matrix.cc +++ b/source/blender/blenlib/intern/math_matrix.cc @@ -325,7 +325,7 @@ MatBase interpolate(const MatBase &A, const MatBase & /* Quaternions cannot represent an axis flip. If such a singularity is detected, choose a * different decomposition of the matrix that still satisfies A = U_A * P_A but which has a - * positive determinant and thus no axis flips. This resolves T77154. + * positive determinant and thus no axis flips. This resolves #77154. * * Note that a flip of two axes is just a rotation of 180 degrees around the third axis, and * three flipped axes are just an 180 degree rotation + a single axis flip. It is thus sufficient diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 180412c4a14..f47bc2d8ed7 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -272,7 +272,7 @@ void quat_to_mat4(float m[4][4], const float q[4]) void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]) { BLI_ASSERT_UNIT_M3(mat); - /* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */ + /* Caller must ensure matrices aren't negative for valid results, see: #24291, #94231. */ BLI_assert(!is_negative_m3(mat)); /* Method outlined by Mike Day, ref: https://math.stackexchange.com/a/3183435/220949 @@ -334,8 +334,8 @@ void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]) } } else { - /* NOTE(@campbellbarton): A zero matrix will fall through to this block, - * needed so a zero scaled matrices to return a quaternion without rotation, see: T101848. */ + /* NOTE(@ideasman42): A zero matrix will fall through to this block, + * needed so a zero scaled matrices to return a quaternion without rotation, see: #101848. */ const float trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2]; float s = 2.0f * sqrtf(trace); q[0] = 0.25f * s; @@ -964,7 +964,7 @@ void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float * /* By default, creating a circle from an integer: calling #sinf & #cosf on the fraction doesn't * create symmetrical values (because floats can't represent Pi exactly). * Resolve this when the rotation is calculated from a fraction by mapping the `numerator` - * to lower values so X/Y values for points around a circle are exactly symmetrical, see T87779. + * to lower values so X/Y values for points around a circle are exactly symmetrical, see #87779. * * Multiply both the `numerator` and `denominator` by eight to ensure we can divide the circle * into 8 octants. For each octant, we then use symmetry and negation to bring the `numerator` diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index 9de75de5ffa..5c15975f393 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -2761,7 +2761,7 @@ static IMesh raycast_tris_boolean(const IMesh &tm, * For most operations, even a hint of being inside * gives good results, but when shape is a cutter in a Difference * operation, we want to be pretty sure that the point is inside other_shape. - * E.g., T75827. + * E.g., #75827. * Also, when the operation is intersection, we also want high confidence. */ bool need_high_confidence = (op == BoolOpType::Difference && shape != 0) || diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c index 2b59de5b569..c5a877a9539 100644 --- a/source/blender/blenlib/intern/polyfill_2d.c +++ b/source/blender/blenlib/intern/polyfill_2d.c @@ -58,7 +58,7 @@ # include "PIL_time_utildefines.h" #endif -typedef signed char eSign; +typedef int8_t eSign; #ifdef USE_KDTREE /** @@ -84,24 +84,24 @@ typedef bool axis_t; /* use for sorting */ typedef struct KDTreeNode2D_head { - uint neg, pos; - uint index; + uint32_t neg, pos; + uint32_t index; } KDTreeNode2D_head; typedef struct KDTreeNode2D { - uint neg, pos; - uint index; + uint32_t neg, pos; + uint32_t index; axis_t axis; /* range is only (0-1) */ - ushort flag; - uint parent; + uint16_t flag; + uint32_t parent; } KDTreeNode2D; struct KDTree2D { KDTreeNode2D *nodes; const float (*coords)[2]; - uint root; - uint node_num; - uint *nodes_map; /* index -> node lookup */ + uint32_t root; + uint32_t node_num; + uint32_t *nodes_map; /* index -> node lookup */ }; struct KDRange2D { @@ -119,14 +119,14 @@ typedef struct PolyFill { struct PolyIndex *indices; /* vertex aligned */ const float (*coords)[2]; - uint coords_num; + uint32_t coords_num; #ifdef USE_CONVEX_SKIP - uint coords_num_concave; + uint32_t coords_num_concave; #endif /* A polygon with n vertices has a triangulation of n-2 triangles. */ - uint (*tris)[3]; - uint tris_num; + uint32_t (*tris)[3]; + uint32_t tris_num; #ifdef USE_KDTREE struct KDTree2D kdtree; @@ -136,7 +136,7 @@ typedef struct PolyFill { /** Circular double linked-list. */ typedef struct PolyIndex { struct PolyIndex *next, *prev; - uint index; + uint32_t index; eSign sign; } PolyIndex; @@ -155,19 +155,18 @@ static PolyIndex *pf_ear_tip_find(PolyFill *pf #endif ); -static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip); +static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip, const eSign sign_accept); static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip); BLI_INLINE eSign signum_enum(float a) { - if (UNLIKELY(a == 0.0f)) { - return 0; - } if (a > 0.0f) { - return 1; + return CONVEX; } - - return -1; + if (UNLIKELY(a == 0.0f)) { + return TANGENTIAL; + } + return CONCAVE; } /** @@ -190,13 +189,13 @@ static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float } #ifdef USE_KDTREE -# define KDNODE_UNSET ((uint)-1) +# define KDNODE_UNSET ((uint32_t)-1) enum { KDNODE_FLAG_REMOVED = (1 << 0), }; -static void kdtree2d_new(struct KDTree2D *tree, uint tot, const float (*coords)[2]) +static void kdtree2d_new(struct KDTree2D *tree, uint32_t tot, const float (*coords)[2]) { /* set by caller */ // tree->nodes = nodes; @@ -208,10 +207,12 @@ static void kdtree2d_new(struct KDTree2D *tree, uint tot, const float (*coords)[ /** * no need for kdtree2d_insert, since we know the coords array. */ -static void kdtree2d_init(struct KDTree2D *tree, const uint coords_num, const PolyIndex *indices) +static void kdtree2d_init(struct KDTree2D *tree, + const uint32_t coords_num, + const PolyIndex *indices) { KDTreeNode2D *node; - uint i; + uint32_t i; for (i = 0, node = tree->nodes; i < coords_num; i++) { if (indices[i].sign != CONVEX) { @@ -223,14 +224,17 @@ static void kdtree2d_init(struct KDTree2D *tree, const uint coords_num, const Po } } - BLI_assert(tree->node_num == (uint)(node - tree->nodes)); + BLI_assert(tree->node_num == (uint32_t)(node - tree->nodes)); } -static uint kdtree2d_balance_recursive( - KDTreeNode2D *nodes, uint node_num, axis_t axis, const float (*coords)[2], const uint ofs) +static uint32_t kdtree2d_balance_recursive(KDTreeNode2D *nodes, + uint32_t node_num, + axis_t axis, + const float (*coords)[2], + const uint32_t ofs) { KDTreeNode2D *node; - uint neg, pos, median, i, j; + uint32_t neg, pos, median, i, j; if (node_num <= 0) { return KDNODE_UNSET; @@ -288,7 +292,7 @@ static void kdtree2d_balance(struct KDTree2D *tree) static void kdtree2d_init_mapping(struct KDTree2D *tree) { - uint i; + uint32_t i; KDTreeNode2D *node; for (i = 0, node = tree->nodes; i < tree->node_num; i++, node++) { @@ -307,9 +311,9 @@ static void kdtree2d_init_mapping(struct KDTree2D *tree) tree->nodes[tree->root].parent = KDNODE_UNSET; } -static void kdtree2d_node_remove(struct KDTree2D *tree, uint index) +static void kdtree2d_node_remove(struct KDTree2D *tree, uint32_t index) { - uint node_index = tree->nodes_map[index]; + uint32_t node_index = tree->nodes_map[index]; KDTreeNode2D *node; if (node_index == KDNODE_UNSET) { @@ -328,7 +332,7 @@ static void kdtree2d_node_remove(struct KDTree2D *tree, uint index) (node->parent != KDNODE_UNSET)) { KDTreeNode2D *node_parent = &tree->nodes[node->parent]; - BLI_assert((uint)(node - tree->nodes) == node_index); + BLI_assert((uint32_t)(node - tree->nodes) == node_index); if (node_parent->neg == node_index) { node_parent->neg = KDNODE_UNSET; } @@ -348,7 +352,7 @@ static void kdtree2d_node_remove(struct KDTree2D *tree, uint index) } static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree, - const uint tri_index[3], + const uint32_t tri_index[3], const float *tri_coords[3], const float tri_center[2], const struct KDRange2D bounds[2], @@ -405,10 +409,10 @@ static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree, return false; } -static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint ind[3]) +static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint32_t ind[3]) { const float *vs[3]; - uint i; + uint32_t i; struct KDRange2D bounds[2] = { {FLT_MAX, -FLT_MAX}, {FLT_MAX, -FLT_MAX}, @@ -433,7 +437,7 @@ static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint ind[3]) #endif /* USE_KDTREE */ -static uint *pf_tri_add(PolyFill *pf) +static uint32_t *pf_tri_add(PolyFill *pf) { return pf->tris[pf->tris_num++]; } @@ -454,7 +458,7 @@ static void pf_coord_remove(PolyFill *pf, PolyIndex *pi) pf->indices = pi->next; } #ifdef DEBUG - pi->index = (uint)-1; + pi->index = (uint32_t)-1; pi->next = pi->prev = NULL; #endif @@ -545,14 +549,16 @@ static void pf_triangulate(PolyFill *pf) } # endif #else +# ifdef USE_CLIP_SWEEP if ((reverse ? pi_prev->prev : pi_next->next)->sign != CONVEX) { reverse = !reverse; } +# endif #endif } if (pf->coords_num == 3) { - uint *tri = pf_tri_add(pf); + uint32_t *tri = pf_tri_add(pf); pi_ear = pf->indices; tri[0] = pi_ear->index; pi_ear = pi_ear->next; @@ -585,27 +591,49 @@ static PolyIndex *pf_ear_tip_find(PolyFill *pf ) { /* localize */ - const uint coords_num = pf->coords_num; + const uint32_t coords_num = pf->coords_num; PolyIndex *pi_ear; - uint i; + uint32_t i; + /* Use two passes when looking for an ear. + * + * - The first pass only picks *good* (concave) choices. + * For polygons which aren't degenerate this works well + * since it avoids creating any zero area faces. + * + * - The second pass is only met if no concave choices are possible, + * so the cost of a second pass is only incurred for degenerate polygons. + * In this case accept zero area faces as better alternatives aren't available. + * + * See: #103913 for reference. + * + * NOTE: these passes draw a distinction between zero area faces and concave + * which is susceptible minor differences in float precision + * (since #TANGENTIAL compares with 0.0f). + * + * While it's possible to compute an error threshold and run a pass that picks + * ears which are more likely not to appear as zero area from a users perspective, + * this API prioritizes performance (for real-time updates). + * Higher quality tessellation can always be achieved using #BLI_polyfill_beautify. + */ + for (eSign sign_accept = CONVEX; sign_accept >= TANGENTIAL; sign_accept--) { #ifdef USE_CLIP_EVEN - pi_ear = pi_ear_init; + pi_ear = pi_ear_init; #else - pi_ear = pf->indices; + pi_ear = pf->indices; #endif - - i = coords_num; - while (i--) { - if (pf_ear_tip_check(pf, pi_ear)) { - return pi_ear; - } + i = coords_num; + while (i--) { + if (pf_ear_tip_check(pf, pi_ear, sign_accept)) { + return pi_ear; + } #ifdef USE_CLIP_SWEEP - pi_ear = reverse ? pi_ear->prev : pi_ear->next; + pi_ear = reverse ? pi_ear->prev : pi_ear->next; #else - pi_ear = pi_ear->next; + pi_ear = pi_ear->next; #endif + } } /* Desperate mode: if no vertex is an ear tip, @@ -638,7 +666,7 @@ static PolyIndex *pf_ear_tip_find(PolyFill *pf return pi_ear; } -static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip) +static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip, const eSign sign_accept) { #ifndef USE_KDTREE /* localize */ @@ -649,7 +677,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip) #endif #if defined(USE_CONVEX_SKIP) && !defined(USE_KDTREE) - uint coords_num_concave_checked = 0; + uint32_t coords_num_concave_checked = 0; #endif #ifdef USE_CONVEX_SKIP @@ -657,7 +685,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip) # ifdef USE_CONVEX_SKIP_TEST /* check if counting is wrong */ { - uint coords_num_concave_test = 0; + uint32_t coords_num_concave_test = 0; PolyIndex *pi_iter = pi_ear_tip; do { if (pi_iter->sign != CONVEX) { @@ -674,13 +702,13 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip) } #endif - if (UNLIKELY(pi_ear_tip->sign == CONCAVE)) { + if (UNLIKELY(pi_ear_tip->sign != sign_accept)) { return false; } #ifdef USE_KDTREE { - const uint ind[3] = {pi_ear_tip->index, pi_ear_tip->next->index, pi_ear_tip->prev->index}; + const uint32_t ind[3] = {pi_ear_tip->index, pi_ear_tip->next->index, pi_ear_tip->prev->index}; if (kdtree2d_isect_tri(&pf->kdtree, ind)) { return false; @@ -729,7 +757,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip) static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip) { - uint *tri = pf_tri_add(pf); + uint32_t *tri = pf_tri_add(pf); tri[0] = pi_ear_tip->prev->index; tri[1] = pi_ear_tip->index; @@ -743,15 +771,15 @@ static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip) */ static void polyfill_prepare(PolyFill *pf, const float (*coords)[2], - const uint coords_num, + const uint32_t coords_num, int coords_sign, - uint (*r_tris)[3], + uint32_t (*r_tris)[3], PolyIndex *r_indices) { /* localize */ PolyIndex *indices = r_indices; - uint i; + uint32_t i; /* assign all polyfill members here */ pf->indices = r_indices; @@ -789,7 +817,7 @@ static void polyfill_prepare(PolyFill *pf, } else { /* reversed */ - uint n = coords_num - 1; + uint32_t n = coords_num - 1; for (i = 0; i < coords_num; i++) { indices[i].next = &indices[i + 1]; indices[i].prev = &indices[i - 1]; @@ -828,9 +856,9 @@ static void polyfill_calc(PolyFill *pf) } void BLI_polyfill_calc_arena(const float (*coords)[2], - const uint coords_num, + const uint32_t coords_num, const int coords_sign, - uint (*r_tris)[3], + uint32_t (*r_tris)[3], struct MemArena *arena) { @@ -873,9 +901,9 @@ void BLI_polyfill_calc_arena(const float (*coords)[2], } void BLI_polyfill_calc(const float (*coords)[2], - const uint coords_num, + const uint32_t coords_num, const int coords_sign, - uint (*r_tris)[3]) + uint32_t (*r_tris)[3]) { /* Fallback to heap memory for large allocations. * Avoid running out of stack memory on systems with 512kb stack (macOS). diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c index 38cf97d6a8f..b6750a46c01 100644 --- a/source/blender/blenlib/intern/polyfill_2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c @@ -205,11 +205,11 @@ static void polyedge_beauty_cost_update_single(const float (*coords)[2], * which leads to infinite loop. Anyway, costs above that are not worth recomputing, * maybe we could even optimize it to a smaller limit? * Actually, FLT_EPSILON is too small in some cases, 1e-6f seems to work OK hopefully? - * See T43578, T49478. + * See #43578, #49478. * * In fact a larger epsilon can still fail when the area of the face is very large, * now the epsilon is scaled by the face area. - * See T56532. */ + * See #56532. */ if (cost < -1e-6f * max_ff(area, 1.0f)) { BLI_heap_insert_or_update(eheap, &eheap_table[i], cost, e); } diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c index 4f057fb348d..4492d8b46cf 100644 --- a/source/blender/blenlib/intern/quadric.c +++ b/source/blender/blenlib/intern/quadric.c @@ -13,7 +13,7 @@ * even though input/output are floats in some cases. * * This is done because the cases quadrics are useful - * often need high precision, see T44780. + * often need high precision, see #44780. */ #include "BLI_math.h" diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 4145125c1d7..04e6ed4a7bb 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -524,11 +524,11 @@ static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) BLI_remlink(&sf_ctx->filledgebase, eed); /* This code is for handling zero-length edges that get * collapsed in step 0. It was removed for some time to - * fix trunk bug T4544, so if that comes back, this code + * fix trunk bug #4544, so if that comes back, this code * may need some work, or there will have to be a better - * fix to T4544. + * fix to #4544. * - * warning, this can hang on un-ordered edges, see: T33281. + * warning, this can hang on un-ordered edges, see: #33281. * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons. */ if (eed->v1->f == SF_VERT_ZERO_LEN) { @@ -660,7 +660,7 @@ static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) * (concave holes) we continue searching and pick the * one with sharpest corner. */ if (best_sc == NULL) { - /* even without holes we need to keep checking T35861. */ + /* even without holes we need to keep checking #35861. */ best_sc = sc1; } else { @@ -867,7 +867,7 @@ uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float n * which historically this function supports so better not change */ /* WARNING: this only gives stable direction with single polygons, - * ideally we'd calculate connectivity and each polys normal, see T41047 */ + * ideally we'd calculate connectivity and each polys normal, see #41047 */ const float *v_prev; zero_v3(n); diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index 8263f8ff34e..bcc866aaab6 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -329,7 +329,7 @@ void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr /** \name Debugging & Introspection * \{ */ -/* NOTE(@campbellbarton): useful for debugging but may not be intended for general use. */ +/* NOTE(@ideasman42): useful for debugging but may not be intended for general use. */ #if 0 void BLI_smallhash_print(SmallHash *sh) { diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 3c3dcaf90f4..4d36cdce5cc 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -402,7 +402,7 @@ bool BLI_str_quoted_substr_range(const char *__restrict str, return true; } -/* NOTE(@campbellbarton): in principal it should be possible to access a quoted string +/* NOTE(@ideasman42): in principal it should be possible to access a quoted string * with an arbitrary size, currently all callers for this functionality * happened to use a fixed size buffer, so only #BLI_str_quoted_substr is needed. */ #if 0 diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index e2124ad4931..c3d370e4cb8 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -45,7 +45,7 @@ static const size_t utf8_skip_data[256] = { ptrdiff_t BLI_str_utf8_invalid_byte(const char *str, size_t length) { - /* NOTE(@campbellbarton): from libswish3, originally called u8_isvalid(), + /* NOTE(@ideasman42): from libswish3, originally called u8_isvalid(), * modified to return the index of the bad character (byte index not UTF). * http://svn.swish-e.org/libswish3/trunk/src/libswish3/utf8.c r3044. * @@ -403,7 +403,7 @@ int BLI_str_utf8_char_width_safe(const char *p) /* copied from glib's gutf8.c, added 'Err' arg */ -/* NOTE(@campbellbarton): glib uses uint for unicode, best we do the same, +/* NOTE(@ideasman42): glib uses uint for unicode, best we do the same, * though we don't typedef it. */ #define UTF8_COMPUTE(Char, Mask, Len, Err) \ diff --git a/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc b/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc index 9b76c7aec44..d1f4ba51fdf 100644 --- a/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc +++ b/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc @@ -388,6 +388,21 @@ TEST(math_matrix_types, ViewMatrixMultiplyOperator) EXPECT_EQ(view[1][1], 46); } +TEST(math_matrix_types, ViewVectorMultiplyOperator) +{ + float4x4 mat = float4x4({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}); + auto view = mat.view<2, 3, 1, 1>(); + + float3 result = view * float2(4, 5); + EXPECT_EQ(result[0], 74); + EXPECT_EQ(result[1], 83); + EXPECT_EQ(result[2], 92); + + float2 result2 = float3(1, 2, 3) * view; + EXPECT_EQ(result2[0], 44); + EXPECT_EQ(result2[1], 68); +} + TEST(math_matrix_types, ViewMatrixNormalize) { float4x4 mat = float4x4({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}); diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc index 140f499ca8e..2d74b40a90d 100644 --- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc +++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc @@ -140,7 +140,7 @@ TEST(math_rotation, quat_to_mat_to_quat_near_0001) test_quat_to_mat_to_quat(0.30f, -0.030f, -0.30f, 0.95f); } -/* A zeroed matrix converted to a quaternion and back should not add rotation, see: T101848 */ +/* A zeroed matrix converted to a quaternion and back should not add rotation, see: #101848 */ TEST(math_rotation, quat_to_mat_to_quat_zeroed_matrix) { float matrix_zeroed[3][3] = {{0.0f}}; diff --git a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc index f3b66bedf88..547300a098e 100644 --- a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc +++ b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc @@ -33,6 +33,12 @@ static void polyfill_to_obj(const char *id, const uint tris[][3], const uint tris_num); +using ePolyFill2DTestFlag = enum ePolyFill2DTestFlag { + POLYFILL2D_TEST_IS_DEGENERATE = (1 << 0), + POLYFILL2D_TEST_NO_ZERO_AREA_TRIS = (1 << 1), + POLYFILL2D_TEST_NOP = 0, +}; + /* -------------------------------------------------------------------- */ /* test utility functions */ @@ -159,13 +165,31 @@ static void test_polyfill_area(const float poly[][2], EXPECT_NEAR(area_total, area_total_tris, eps); } +/** + * Check that none of the tessellated triangles are zero area. + */ +static void test_polyfill_area_tri_nonzero(const float poly[][2], + const uint /*poly_num*/, + const uint tris[][3], + const uint tris_num) +{ + uint i; + uint total = 0; + for (i = 0; i < tris_num; i++) { + if (area_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]) < 1e-6f) { + total += 1; + } + } + EXPECT_EQ(total, 0); +} + /* -------------------------------------------------------------------- */ /* Macro and helpers to manage checking */ /** * Main template for polyfill testing. */ static void test_polyfill_template_check(const char *id, - bool is_degenerate, + const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, const uint tris[][3], @@ -173,16 +197,22 @@ static void test_polyfill_template_check(const char *id, { test_polyfill_simple(poly, poly_num, tris, tris_num); test_polyfill_topology(poly, poly_num, tris, tris_num); - if (!is_degenerate) { + if (!(test_flag & POLYFILL2D_TEST_IS_DEGENERATE)) { test_polyfill_winding(poly, poly_num, tris, tris_num); test_polyfill_area(poly, poly_num, tris, tris_num); + + /* Only check when non-degenerate, because the number of zero area triangles + * are undefined for degenerate polygons as there is no correct solution. */ + if (test_flag & POLYFILL2D_TEST_NO_ZERO_AREA_TRIS) { + test_polyfill_area_tri_nonzero(poly, poly_num, tris, tris_num); + } } polyfill_to_obj(id, poly, poly_num, tris, tris_num); } static void test_polyfill_template(const char *id, - bool is_degenerate, + const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], @@ -192,7 +222,7 @@ static void test_polyfill_template(const char *id, BLI_polyfill_calc(poly, poly_num, 0, tris); /* check all went well */ - test_polyfill_template_check(id, is_degenerate, poly, poly_num, tris, tris_num); + test_polyfill_template_check(id, test_flag, poly, poly_num, tris, tris_num); #ifdef USE_BEAUTIFY /* check beautify gives good results too */ @@ -202,7 +232,7 @@ static void test_polyfill_template(const char *id, BLI_polyfill_beautify(poly, poly_num, tris, pf_arena, pf_heap); - test_polyfill_template_check(id, is_degenerate, poly, poly_num, tris, tris_num); + test_polyfill_template_check(id, test_flag, poly, poly_num, tris, tris_num); BLI_memarena_free(pf_arena); BLI_heap_free(pf_heap, nullptr); @@ -211,7 +241,7 @@ static void test_polyfill_template(const char *id, } static void test_polyfill_template_flip_sign(const char *id, - bool is_degenerate, + const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], @@ -226,7 +256,7 @@ static void test_polyfill_template_flip_sign(const char *id, poly_copy[i][0] = poly[i][0] * sign_x; poly_copy[i][1] = poly[i][1] * sign_y; } - test_polyfill_template(id, is_degenerate, poly_copy, poly_num, tris, tris_num); + test_polyfill_template(id, test_flag, poly_copy, poly_num, tris, tris_num); } } MEM_freeN(poly_copy); @@ -234,7 +264,7 @@ static void test_polyfill_template_flip_sign(const char *id, #ifdef USE_COMBINATIONS_ALL static void test_polyfill_template_main(const char *id, - bool is_degenerate, + const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], @@ -256,7 +286,7 @@ static void test_polyfill_template_main(const char *id, for (poly_cycle = 0; poly_cycle < poly_num; poly_cycle++) { // printf("polytest %s ofs=%d, reverse=%d\n", id, poly_cycle, poly_reverse); - test_polyfill_template_flip_sign(id, is_degenerate, poly, poly_num, tris, tris_num); + test_polyfill_template_flip_sign(id, test_flag, poly, poly_num, tris, tris_num); /* cycle */ copy_v2_v2(tmp, poly_copy[0]); @@ -269,24 +299,24 @@ static void test_polyfill_template_main(const char *id, } #else /* USE_COMBINATIONS_ALL */ static void test_polyfill_template_main(const char *id, - bool is_degenerate, + const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], const uint tris_num) { - test_polyfill_template_flip_sign(id, is_degenerate, poly, poly_num, tris, tris_num); + test_polyfill_template_flip_sign(id, test_flag, poly, poly_num, tris, tris_num); } #endif /* USE_COMBINATIONS_ALL */ -#define TEST_POLYFILL_TEMPLATE_STATIC(poly, is_degenerate) \ +#define TEST_POLYFILL_TEMPLATE_STATIC(poly, test_flag) \ { \ uint tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \ const uint poly_num = ARRAY_SIZE(poly); \ const uint tris_num = ARRAY_SIZE(tris); \ const char *id = typeid(*this).name(); \ \ - test_polyfill_template_main(id, is_degenerate, poly, poly_num, tris, tris_num); \ + test_polyfill_template_main(id, test_flag, poly, poly_num, tris, tris_num); \ } \ (void)0 @@ -380,56 +410,56 @@ static void polyfill_to_obj(const char *id, TEST(polyfill2d, TriangleCCW) { const float poly[][2] = {{0, 0}, {0, 1}, {1, 0}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* A counterclockwise square */ TEST(polyfill2d, SquareCCW) { const float poly[][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* A clockwise square */ TEST(polyfill2d, SquareCW) { const float poly[][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Starfleet insigna */ TEST(polyfill2d, Starfleet) { const float poly[][2] = {{0, 0}, {0.6f, 0.4f}, {1, 0}, {0.5f, 1}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Starfleet insigna with repeated point */ TEST(polyfill2d, StarfleetDegenerate) { const float poly[][2] = {{0, 0}, {0.6f, 0.4f}, {0.6f, 0.4f}, {1, 0}, {0.5f, 1}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Three collinear points */ TEST(polyfill2d, 3Colinear) { const float poly[][2] = {{0, 0}, {1, 0}, {2, 0}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Four collinear points */ TEST(polyfill2d, 4Colinear) { const float poly[][2] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Non-consecutive collinear points */ TEST(polyfill2d, UnorderedColinear) { const float poly[][2] = {{0, 0}, {1, 1}, {2, 0}, {3, 1}, {4, 0}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Plus shape */ @@ -449,14 +479,14 @@ TEST(polyfill2d, PlusShape) {0, 1}, {1, 1}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Star shape */ TEST(polyfill2d, StarShape) { const float poly[][2] = {{4, 0}, {5, 3}, {8, 4}, {5, 5}, {4, 8}, {3, 5}, {0, 4}, {3, 3}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* U shape */ @@ -464,7 +494,7 @@ TEST(polyfill2d, UShape) { const float poly[][2] = { {1, 0}, {2, 0}, {3, 1}, {3, 3}, {2, 3}, {2, 1}, {1, 1}, {1, 3}, {0, 3}, {0, 1}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Spiral */ @@ -488,7 +518,7 @@ TEST(polyfill2d, Spiral) {4, 1}, {0, 1}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Test case from http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml */ @@ -511,14 +541,14 @@ TEST(polyfill2d, TestFlipCode) {4, 3}, {2, 6}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Self-intersection */ TEST(polyfill2d, SelfIntersect) { const float poly[][2] = {{0, 0}, {1, 1}, {2, -1}, {3, 1}, {4, 0}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, true); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_IS_DEGENERATE); } /* Self-touching */ @@ -538,7 +568,7 @@ TEST(polyfill2d, SelfTouch) {2, 4}, {0, 4}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Self-overlapping */ @@ -558,7 +588,7 @@ TEST(polyfill2d, SelfOverlap) {3, 4}, {0, 4}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, true); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_IS_DEGENERATE); } /* Test case from http://www.davdata.nl/math/polygons.html */ @@ -570,7 +600,7 @@ TEST(polyfill2d, TestDavData) {410, 30}, {470, 440}, {640, 410}, {630, 140}, {590, 140}, {580, 360}, {510, 370}, {510, 60}, {650, 70}, {660, 450}, {190, 480}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Issue 815, http://code.google.com/p/libgdx/issues/detail?id=815 */ @@ -586,7 +616,7 @@ TEST(polyfill2d, Issue815) {2.0f, 1.0f}, {2.0f, 0.0f}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Issue 207, comment #1, http://code.google.com/p/libgdx/issues/detail?id=207#c1 */ @@ -605,7 +635,7 @@ TEST(polyfill2d, Issue207_1) {126.70667f, 170.07617f}, {73.22717f, 199.51062f}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, true); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_IS_DEGENERATE); } /* Issue 207, comment #11, http://code.google.com/p/libgdx/issues/detail?id=207#c11 */ @@ -625,7 +655,7 @@ TEST(polyfill2d, Issue207_11) {1934.0381f, 485.3833f}, {1934.5234f, 484.11328f}, {1934.9502f, 482.9663f}, {1935.3125f, 481.96875f}, {1935.6045f, 481.14697f}, {1935.8203f, 480.52734f}, {1935.9541f, 480.13623f}, {1936.0f, 480.0f}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Issue 1407, http://code.google.com/p/libgdx/issues/detail?id=1407 */ @@ -637,7 +667,7 @@ TEST(polyfill2d, Issue1407) {4.8973203f, 1.9063174f}, {5.4979978f, 1.9096732f}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } /* Issue 1407, http://code.google.com/p/libgdx/issues/detail?id=1407, */ @@ -651,10 +681,10 @@ TEST(polyfill2d, Issue1407_pt) {5.4979978f, 1.9096732f}, {4, 4}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } -/* Simplified from Blender bug T40777 */ +/* Simplified from Blender bug #40777 */ TEST(polyfill2d, IssueT40777_colinear) { const float poly[][2] = { @@ -662,10 +692,10 @@ TEST(polyfill2d, IssueT40777_colinear) {0.88, 0.4}, {0.94, 0.4}, {0.94, 0}, {1, 0}, {1, 0.4}, {0.03, 0.62}, {0.03, 0.89}, {0.59, 0.89}, {0.03, 1}, {0, 1}, {0, 0}, {0.03, 0}, {0.03, 0.37}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } -/* Blender bug T41986 */ +/* Blender bug #41986 */ TEST(polyfill2d, IssueT41986_axis_align) { const float poly[][2] = { @@ -677,10 +707,10 @@ TEST(polyfill2d, IssueT41986_axis_align) {0.68, 0.06}, {0.57, -0.36}, {-0.25, -0.37}, {0.49, -0.74}, {-0.59, -1.21}, {-0.25, -0.15}, {-0.46, -0.52}, {-1.08, -0.83}, {-1.45, -0.33}, {-1.25, -0.04}}; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } -/* Blender bug T52834 */ +/* Blender bug #52834 */ TEST(polyfill2d, IssueT52834_axis_align_co_linear) { const float poly[][2] = { @@ -692,10 +722,10 @@ TEST(polyfill2d, IssueT52834_axis_align_co_linear) {18, -2}, {23, -2}, {24, -2}, {29, -2}, {30, -2}, {35, -2}, {36, -2}, {40, -2}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } -/* Blender bug T67109 (version a). */ +/* Blender bug #67109 (version a). */ /* Multiple versions are offset & rotated, this fails in cases where others works. */ TEST(polyfill2d, IssueT67109_axis_align_co_linear_a) { @@ -711,10 +741,10 @@ TEST(polyfill2d, IssueT67109_axis_align_co_linear_a) {2.8720665, -2.6659985}, {2.8720665, -0.15499878}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } -/* Blender bug T67109, (version b). */ +/* Blender bug #67109, (version b). */ TEST(polyfill2d, IssueT67109_axis_align_co_linear_b) { const float poly[][2] = { @@ -729,10 +759,10 @@ TEST(polyfill2d, IssueT67109_axis_align_co_linear_b) {25.825695, -6.320076}, {24.00582, -4.5899982}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); } -/* Blender bug T67109 (version c). */ +/* Blender bug #67109 (version c). */ TEST(polyfill2d, IssueT67109_axis_align_co_linear_c) { const float poly[][2] = { @@ -747,5 +777,19 @@ TEST(polyfill2d, IssueT67109_axis_align_co_linear_c) {-60.546703, 71.07365}, {-58.37554, 78.83239}, }; - TEST_POLYFILL_TEMPLATE_STATIC(poly, false); + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NOP); +} + +/* Blender bug #103913 where co-linear edges create zero area tessellation + * when a valid solution exists without zero area triangles. */ +TEST(polyfill2d, Issue103913_axis_align_co_linear_no_zero_area_tri) +{ + const float poly[][2] = { + {-10, 0}, {-10, 2}, {-8, 2}, {-6, 2}, {-4, 2}, {-2, 2}, {-2, 4}, {-2, 6}, + {-2, 8}, {-2, 10}, {0, 10}, {2, 10}, {2, 8}, {2, 6}, {2, 4}, {2, 2}, + {4, 2}, {6, 2}, {8, 2}, {10, 2}, {10, 0}, {10, -2}, {8, -2}, {6, -2}, + {4, -2}, {2, -2}, {2, -4}, {2, -6}, {2, -8}, {2, -10}, {0, -10}, {-2, -10}, + {-2, -8}, {-2, -6}, {-2, -4}, {-2, -2}, {-4, -2}, {-6, -2}, {-8, -2}, {-10, -2}, + }; + TEST_POLYFILL_TEMPLATE_STATIC(poly, POLYFILL2D_TEST_NO_ZERO_AREA_TRIS); } diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc index d726fbccf20..9ea46f22890 100644 --- a/source/blender/blenlib/tests/BLI_string_test.cc +++ b/source/blender/blenlib/tests/BLI_string_test.cc @@ -612,6 +612,25 @@ TEST(string, StrFormatIntegerUnits) EXPECT_STREQ("-2B", size_str); } +TEST(string, StringNLen) +{ + EXPECT_EQ(0, BLI_strnlen("", 0)); + EXPECT_EQ(0, BLI_strnlen("", 1)); + EXPECT_EQ(0, BLI_strnlen("", 100)); + + EXPECT_EQ(0, BLI_strnlen("x", 0)); + EXPECT_EQ(1, BLI_strnlen("x", 1)); + EXPECT_EQ(1, BLI_strnlen("x", 100)); + + // ü is \xc3\xbc + EXPECT_EQ(2, BLI_strnlen("ü", 100)); + + EXPECT_EQ(0, BLI_strnlen("this is a longer string", 0)); + EXPECT_EQ(1, BLI_strnlen("this is a longer string", 1)); + EXPECT_EQ(5, BLI_strnlen("this is a longer string", 5)); + EXPECT_EQ(47, BLI_strnlen("This string writes about an agent without name.", 100)); +} + struct WordInfo { WordInfo() = default; WordInfo(int start, int end) : start(start), end(end) diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h index 35768cb7e7a..f1685d079e4 100644 --- a/source/blender/blenloader/BLO_read_write.h +++ b/source/blender/blenloader/BLO_read_write.h @@ -288,7 +288,7 @@ void BLO_expand_id(BlendExpander *expander, struct ID *id); * This function ensures that reports are printed, * in the case of library linking errors this is important! * - * NOTE(@campbellbarton) a kludge but better than doubling up on prints, + * NOTE(@ideasman42) a kludge but better than doubling up on prints, * we could alternatively have a versions of a report function which forces printing. */ void BLO_reportf_wrap(struct BlendFileReadReport *reports, diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index c440dbf8c7a..29730f7f10a 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -162,7 +162,7 @@ * which keeps large arrays in memory from data-blocks we may not even use. * * \note This is disabled when using compression, - * while ZLIB supports seek it's unusably slow, see: T61880. + * while ZLIB supports seek it's unusably slow, see: #61880. */ #define USE_BHEAD_READ_ON_DEMAND @@ -2038,7 +2038,7 @@ static void direct_link_id_common( /* No-main and other types of special IDs should never be written in .blend files. */ /* NOTE: `NO_MAIN` is commented for now as some code paths may still generate embedded IDs with - * this tag, see T103389. Related to T88555. */ + * this tag, see #103389. Related to #88555. */ BLI_assert( (id->tag & (/*LIB_TAG_NO_MAIN |*/ LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0); @@ -2111,7 +2111,7 @@ static void direct_link_id_common( /* Link direct data of overrides. */ if (id->override_library) { BLO_read_data_address(reader, &id->override_library); - /* Work around file corruption on writing, see T86853. */ + /* Work around file corruption on writing, see #86853. */ if (id->override_library != nullptr) { BLO_read_list_cb( reader, &id->override_library->properties, direct_link_id_override_property_cb); @@ -2471,7 +2471,7 @@ static void lib_link_workspace_layout_restore(IDNameLib_Map *id_map, sbuts->flag &= ~SB_PIN_CONTEXT; } - /* TODO: restore path pointers: T40046 + /* TODO: restore path pointers: #40046 * (complicated because this contains data pointers too, not just ID). */ MEM_SAFE_FREE(sbuts->path); break; @@ -2496,7 +2496,7 @@ static void lib_link_workspace_layout_restore(IDNameLib_Map *id_map, } /* force recalc of list of channels, potentially updating the active action - * while we're at it (as it can only be updated that way) T28962. + * while we're at it (as it can only be updated that way) #28962. */ saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC; break; @@ -2731,7 +2731,7 @@ void blo_lib_link_restore(Main *oldmain, /* Restore all ID pointers in Main database itself * (especially IDProperties might point to some word-space of other 'weirdly unchanged' ID - * pointers, see T69146). + * pointers, see #69146). * Note that this will re-apply again a few pointers in workspaces or so, * but since we are remapping final ones already set above, * that is just some minor harmless double-processing. */ @@ -2774,7 +2774,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) * where to add all non-library data-blocks found in file next, we have to switch that * 'dupli' found Main to latest position in the list! * Otherwise, you get weird disappearing linked data on a rather inconsistent basis. - * See also T53977 for reproducible case. */ + * See also #53977 for reproducible case. */ BLI_remlink(fd->mainlist, newmain); BLI_addtail(fd->mainlist, newmain); @@ -2817,7 +2817,7 @@ static void fix_relpaths_library(const char *basepath, Main *main) /* when loading a linked lib into a file which has not been saved, * there is nothing we can be relative to, so instead we need to make * it absolute. This can happen when appending an object with a relative - * link into an unsaved blend file. See T27405. + * link into an unsaved blend file. See #27405. * The remap relative option will make it relative again on save - campbell */ if (BLI_path_is_rel(lib->filepath)) { BLI_strncpy(lib->filepath, lib->filepath_abs, sizeof(lib->filepath)); @@ -3078,7 +3078,7 @@ static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const I * (see BLO_read_from_memfile). * However, some needed by the snapshot being read may have been removed in previous one, * and would go missing. - * This leads e.g. to disappearing objects in some undo/redo case, see T34446. + * This leads e.g. to disappearing objects in some undo/redo case, see #34446. * That means we have to carefully check whether current lib or * libdata already exits in old main, if it does we merely copy it over into new main area, * otherwise we have to do a full read of that bhead... */ @@ -3982,8 +3982,8 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) BKE_lib_override_library_main_update(bfd->main); /* FIXME Temporary 'fix' to a problem in how temp ID are copied in - * `BKE_lib_override_library_main_update`, see T103062. - * Proper fix involves first addressing T90610. */ + * `BKE_lib_override_library_main_update`, see #103062. + * Proper fix involves first addressing #90610. */ BKE_main_collections_parent_relations_rebuild(bfd->main); fd->reports->duration.lib_overrides = PIL_check_seconds_timer() - @@ -4612,8 +4612,8 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag) BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false); /* FIXME Temporary 'fix' to a problem in how temp ID are copied in - * `BKE_lib_override_library_main_update`, see T103062. - * Proper fix involves first addressing T90610. */ + * `BKE_lib_override_library_main_update`, see #103062. + * Proper fix involves first addressing #90610. */ BKE_main_collections_parent_relations_rebuild(mainvar); /* Make all relative paths, relative to the open blend file. */ diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 5d2072e0fd9..fb806a0b124 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -2115,7 +2115,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 258, 1)) { - /* screen view2d settings were not properly initialized T27164. + /* screen view2d settings were not properly initialized #27164. * v2d->scroll caused the bug but best reset other values too * which are in old blend files only. * Need to make less ugly - possibly an iterator? */ diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 8cfd66576ff..0a4211315c0 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -1587,7 +1587,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) /* correction for files saved in blender version when BKE_pose_copy_data * didn't copy animation visualization, which lead to deadlocks on motion - * path calculation for proxied armatures, see T32742. + * path calculation for proxied armatures, see #32742. */ if (bmain->versionfile < 264) { Object *ob; diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 5d966344717..067918976c7 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -409,7 +409,7 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), FMod_Stepped *data = fcm->data; /* Modifier doesn't work if the modifier's copy of start/end frame are both 0 - * as those were only getting written to the fcm->data copy (T52009) + * as those were only getting written to the fcm->data copy (#52009) */ if ((fcm->sfra == fcm->efra) && (fcm->sfra == 0)) { fcm->sfra = data->start_frame; @@ -557,7 +557,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 270, 4)) { /* ui_previews were not handled correctly when copying areas, - * leading to corrupted files (see T39847). + * leading to corrupted files (see #39847). * This will always reset situation to a valid state. */ bScreen *screen; @@ -1551,7 +1551,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /* Fix for T50736, Glare comp node using same var for two different things. */ + /* Fix for #50736, Glare comp node using same var for two different things. */ if (!DNA_struct_elem_find(fd->filesdna, "NodeGlare", "char", "star_45")) { FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_COMPOSIT) { @@ -1602,7 +1602,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /* Fix related to VGroup modifiers creating named defgroup CD layers! See T51520. */ + /* Fix related to VGroup modifiers creating named defgroup CD layers! See #51520. */ for (Mesh *me = bmain->meshes.first; me; me = me->id.next) { CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, ""); } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 2e9a16bc945..ff860677663 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1206,7 +1206,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) } if (collection_hidden == NULL) { /* This should never happen (objects are always supposed to be instantiated in a - * scene), but it does sometimes, see e.g. T81168. + * scene), but it does sometimes, see e.g. #81168. * Just put them in first hidden collection in those cases. */ collection_hidden = &hidden_collection_array[0]; } @@ -1739,7 +1739,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) /* NOTE: This version patch is intended for versions < 2.52.2, * but was initially introduced in 2.27 already. * But in 2.79 another case generating non-unique names was discovered - * (see T55668, involving Meta strips). */ + * (see #55668, involving Meta strips). */ static void do_versions_seq_unique_name_all_strips(Scene *sce, ListBase *seqbasep) { for (Sequence *seq = seqbasep->first; seq != NULL; seq = seq->next) { diff --git a/source/blender/blenloader/intern/versioning_290.cc b/source/blender/blenloader/intern/versioning_290.cc index 9c968e905cf..b90e7529bbc 100644 --- a/source/blender/blenloader/intern/versioning_290.cc +++ b/source/blender/blenloader/intern/versioning_290.cc @@ -721,7 +721,7 @@ static void do_versions_point_attributes(CustomData *pdata) static void do_versions_point_attribute_names(CustomData *pdata) { - /* Change from capital initial letter to lower case (T82693). */ + /* Change from capital initial letter to lower case (#82693). */ for (int i = 0; i < pdata->totlayer; i++) { CustomDataLayer *layer = &pdata->layers[i]; if (layer->type == CD_PROP_FLOAT3 && STREQ(layer->name, "Position")) { @@ -841,7 +841,7 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain) } } - /** Repair files from duplicate brushes added to blend files, see: T76738. */ + /** Repair files from duplicate brushes added to blend files, see: #76738. */ if (!MAIN_VERSION_ATLEAST(bmain, 290, 2)) { { short id_codes[] = {ID_BR, ID_PAL}; @@ -1156,7 +1156,7 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 291, 5)) { - /* Fix fcurves to allow for new bezier handles behavior (T75881 and D8752). */ + /* Fix fcurves to allow for new bezier handles behavior (#75881 and D8752). */ LISTBASE_FOREACH (bAction *, act, &bmain->actions) { LISTBASE_FOREACH (FCurve *, fcu, &act->curves) { /* Only need to fix Bezier curves with at least 2 key-frames. */ diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 4c45e1433ab..e8e7c6b552a 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -2251,7 +2251,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 300, 9)) { /* Fix a bug where reordering FCurves and bActionGroups could cause some corruption. Just * reconstruct all the action groups & ensure that the FCurves of a group are continuously - * stored (i.e. not mixed with other groups) to be sure. See T89435. */ + * stored (i.e. not mixed with other groups) to be sure. See #89435. */ LISTBASE_FOREACH (bAction *, act, &bmain->actions) { BKE_action_groups_reconstruct(act); } @@ -2363,7 +2363,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } - /* Font names were copied directly into ID names, see: T90417. */ + /* Font names were copied directly into ID names, see: #90417. */ if (!MAIN_VERSION_ATLEAST(bmain, 300, 16)) { ListBase *lb = which_libbase(bmain, ID_VF); BKE_main_id_repair_duplicate_names_listbase(bmain, lb); @@ -3606,7 +3606,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 303, 5)) { - /* Fix for T98925 - remove channels region, that was initialized in incorrect editor types. */ + /* Fix for #98925 - remove channels region, that was initialized in incorrect editor types. */ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { @@ -3636,7 +3636,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } /* Disable 'show_bounds' option of curve objects. Option was set as there was no object mode - * outline implementation. See T95933. */ + * outline implementation. See #95933. */ LISTBASE_FOREACH (Object *, ob, &bmain->objects) { if (ob->type == OB_CURVES) { ob->dtx &= ~OB_DRAWBOUNDOX; @@ -3738,7 +3738,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 304, 5)) { - /* Fix for T101622 - update flags of sequence editor regions that were not initialized + /* Fix for #101622 - update flags of sequence editor regions that were not initialized * properly. */ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { @@ -3779,15 +3779,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } - if (!MAIN_VERSION_ATLEAST(bmain, 305, 1)) { - /* Reset edge visibility flag, since the base is meant to be "true" for original meshes. */ - LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { - for (MEdge &edge : mesh->edges_for_write()) { - edge.flag |= ME_EDGEDRAW; - } - } - } - if (!MAIN_VERSION_ATLEAST(bmain, 305, 2)) { LISTBASE_FOREACH (MovieClip *, clip, &bmain->movieclips) { MovieTracking *tracking = &clip->tracking; @@ -3901,6 +3892,21 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 9)) { + /* Enable legacy normal and rotation outputs in Distribute Points on Faces node. */ + LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { + if (ntree->type != NTREE_GEOMETRY) { + continue; + } + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + if (node->type != GEO_NODE_DISTRIBUTE_POINTS_ON_FACES) { + continue; + } + node->custom2 = true; + } + } + } + /** * Versioning code until next subversion bump goes here. * @@ -3911,6 +3917,15 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) * \note Keep this message at the bottom of the function. */ { + if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "int", "shadow_pool_size")) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + scene->eevee.flag |= SCE_EEVEE_SHADOW_ENABLED; + scene->eevee.shadow_pool_size = 512; + scene->r.simplify_shadows = 1.0f; + scene->r.simplify_shadows_render = 1.0f; + } + } + /* Keep this block, even when empty. */ } } diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index f6fe45ddcdf..d19616223cd 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -82,7 +82,7 @@ static void blo_update_defaults_screen(bScreen *screen, LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { /* Some toolbars have been saved as initialized, - * we don't want them to have odd zoom-level or scrolling set, see: T47047 */ + * we don't want them to have odd zoom-level or scrolling set, see: #47047 */ if (ELEM(region->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) { region->v2d.flag &= ~V2D_IS_INIT; } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 8685db377d4..63fc349ca39 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -1467,7 +1467,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) for (me = bmain->meshes.first; me; me = me->id.next) { if (!me->medge) { - BKE_mesh_calc_edges_legacy(me, true); /* true = use #MFace.edcode. */ + BKE_mesh_calc_edges_legacy(me); } else { BKE_mesh_strip_loose_faces(me); diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index 57ac9d650d9..a95e3180b67 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -788,7 +788,7 @@ static void current_screen_compat(Main *mainvar, if (wm) { if (use_active_win) { - /* write the active window into the file, needed for multi-window undo T43424 */ + /* write the active window into the file, needed for multi-window undo #43424 */ for (window = static_cast(wm->windows.first); window; window = window->next) { if (window->active) { break; @@ -1472,7 +1472,7 @@ bool BLO_write_file(Main *mainvar, if (remap_mode != BLO_WRITE_PATH_REMAP_NONE) { /* Some path processing (e.g. with libraries) may use the current `main->filepath`, if this * is not matching the path currently used for saving, unexpected paths corruptions can - * happen. See T98201. */ + * happen. See #98201. */ char mainvar_filepath_orig[FILE_MAX]; STRNCPY(mainvar_filepath_orig, mainvar->filepath); STRNCPY(mainvar->filepath, filepath); diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 16db91595ec..8f21ed63df2 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -827,7 +827,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) } if (oldpool) { - /* this should never happen but can when dissolve fails - T28960. */ + /* this should never happen but can when dissolve fails - #28960. */ BLI_assert(data->pool != oldpool); BLI_mempool_destroy(oldpool); diff --git a/source/blender/bmesh/intern/bmesh_iterators.cc b/source/blender/bmesh/intern/bmesh_iterators.cc index 91ece97fa21..d712fe8c731 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.cc +++ b/source/blender/bmesh/intern/bmesh_iterators.cc @@ -352,7 +352,7 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const * VERT OF MESH CALLBACKS */ -/* see bug T36923 for why we need this, +/* see bug #36923 for why we need this, * allow adding but not removing, this isn't _totally_ safe since * you could add/remove within the same loop, but catches common cases */ diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index e4319c23c4e..d84f163f978 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -77,7 +77,7 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX]; BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++) /* a version of BM_ITER_MESH which keeps the next item in storage - * so we can delete the current item, see bug T36923. */ + * so we can delete the current item, see bug #36923. */ #ifdef DEBUG # define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \ diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index a8a9390f525..e44bf2d4b09 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -305,7 +305,7 @@ static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces) f->head.hflag = lf->hflag; bm_log_face_id_set(log, f, POINTER_AS_UINT(key)); - /* Ensure face sets have valid values. Fixes T80174. */ + /* Ensure face sets have valid values. Fixes #80174. */ if (cd_face_sets != -1) { BM_ELEM_CD_SET_INT(f, cd_face_sets, 1); } diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index a1c2815ab2f..a81e70b4e67 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -604,7 +604,7 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select) * * Rely on #BM_mesh_select_mode_flush to correct these cases. * - * \note flushing based on mode, see T46494 + * \note flushing based on mode, see #46494 */ if (bm->selectmode & SCE_SELECT_VERTEX) { l_iter = l_first = BM_FACE_FIRST_LOOP(f); diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index d58337400a2..4ec30e12ba2 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -113,7 +113,7 @@ using blender::StringRef; static char bm_edge_flag_from_mflag(const short mflag) { - return ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0); + return ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | BM_ELEM_DRAW; } static char bm_face_flag_from_mflag(const char mflag) { @@ -124,7 +124,7 @@ static short bm_edge_flag_to_mflag(const BMEdge *e) { const char hflag = e->head.hflag; - return ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0); + return (hflag & BM_ELEM_SEAM) ? ME_SEAM : 0; } static char bm_face_flag_to_mflag(const BMFace *f) { @@ -133,6 +133,20 @@ static char bm_face_flag_to_mflag(const BMFace *f) return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0); } +bool BM_attribute_stored_in_bmesh_builtin(const StringRef name) +{ + return ELEM(name, + "position", + ".hide_vert", + ".hide_edge", + ".hide_poly", + ".select_vert", + ".select_edge", + ".select_poly", + "material_index", + "sharp_edge"); +} + /* Static function for alloc (duplicate in modifiers_bmesh.c) */ static BMFace *bm_face_create_from_mpoly(BMesh &bm, Span loops, @@ -587,7 +601,7 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert) * ===================== * * Key blocks locations must *not* be used. This was done from v2.67 to 3.0, - * causing bugs T35170 & T44415. + * causing bugs #35170 & #44415. * * Shape key synchronizing could work under the assumption that the key-block is * fixed-in-place when entering edit-mode allowing them to be used as a reference when exiting. @@ -762,7 +776,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Without this, the real mesh coordinates (uneditable) as soon as you create the Basis shape. * while users might not notice since the shape-key is applied in the viewport, - * exporters for example may still use the underlying coordinates, see: T30771 & T96135. + * exporters for example may still use the underlying coordinates, see: #30771 & #96135. * * Needed when editing any shape that isn't the (`key->refkey`), the vertices in mesh positions * currently have vertex coordinates set from the current-shape (initialized from #BMVert.co). @@ -832,7 +846,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Apply back new coordinates shape-keys that have offset into #BMesh. * Otherwise, in case we call again #BM_mesh_bm_to_me on same #BMesh, * we'll apply diff from previous call to #BM_mesh_bm_to_me, - * to shape-key values from original creation of the #BMesh. See T50524. */ + * to shape-key values from original creation of the #BMesh. See #50524. */ copy_v3_v3(co_orig, currkey_data[i]); } } @@ -859,7 +873,7 @@ static void bm_to_mesh_shape(BMesh *bm, ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) && (keyi < currkey->totelem)) { /* Reconstruct keys via vertices original key indices. - * WARNING(@campbellbarton): `currkey->data` is known to be unreliable as the edit-mesh + * WARNING(@ideasman42): `currkey->data` is known to be unreliable as the edit-mesh * coordinates may be flushed back to the shape-key when exporting or rendering. * This is a last resort! If this branch is running as part of regular usage * it can be considered a bug. */ @@ -1012,7 +1026,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh me->totloop = bm->totloop; me->totpoly = bm->totface; /* Will be overwritten with a valid value if 'dotess' is set, otherwise we - * end up with 'me->totface' and `me->mface == nullptr` which can crash T28625. */ + * end up with 'me->totface' and `me->mface == nullptr` which can crash #28625. */ me->totface = 0; me->act_face = -1; @@ -1420,15 +1434,6 @@ static void bm_to_mesh_edges(const BMesh &bm, dst_edge.v1 = BM_elem_index_get(src_edge.v1); dst_edge.v2 = BM_elem_index_get(src_edge.v2); dst_edge.flag = bm_edge_flag_to_mflag(&src_edge); - - /* Handle this differently to editmode switching; only enable draw for single user - * edges rather than calculating angle. */ - if ((dst_edge.flag & ME_EDGEDRAW) == 0) { - if (src_edge.l && src_edge.l == src_edge.l->radial_next) { - dst_edge.flag |= ME_EDGEDRAW; - } - } - CustomData_from_bmesh_block(&bm.edata, &mesh.edata, src_edge.head.data, edge_i); } if (!select_edge.is_empty()) { diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.h b/source/blender/bmesh/intern/bmesh_mesh_convert.h index 82b6d41b19b..822e7997ea3 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.h +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.h @@ -9,6 +9,16 @@ #include "bmesh.h" +#ifdef __cplusplus +# include "BLI_string_ref.hh" + +/** + * \return Whether attributes with the given name are stored in special flags or fields in BMesh + * rather than in the regular custom data blocks. + */ +bool BM_attribute_stored_in_bmesh_builtin(const blender::StringRef name); +#endif + #ifdef __cplusplus extern "C" { #endif @@ -51,7 +61,7 @@ struct BMeshToMeshParams { * * This is needed when flushing changes from edit-mode into object mode, * so a second flush or edit-mode exit doesn't run with indices - * that have become invalid from updating the shape-key, see T71865. + * that have become invalid from updating the shape-key, see #71865. */ bool update_shapekey_indices; /** @@ -82,7 +92,6 @@ void BM_mesh_bm_to_me(struct Main *bmain, * - Ignore shape-keys. * - Ignore vertex-parents. * - Ignore selection history. - * - Uses simpler method to calculate #ME_EDGEDRAW * - Uses #CD_MASK_DERIVEDMESH instead of #CD_MASK_MESH. * * \note Was `cddm_from_bmesh_ex` in 2.7x, removed `MFace` support. diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.cc b/source/blender/bmesh/intern/bmesh_mesh_normals.cc index 03bd1811fd8..28164eaec7a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.cc @@ -1057,7 +1057,7 @@ static void bm_mesh_loops_calc_normals_for_vert_without_clnors( * Will use first clnors_data array, and fallback to cd_loop_clnors_offset * (use nullptr and -1 to not use clnors). * - * \note This sets #BM_ELEM_TAG which is used in tool code (e.g. T84426). + * \note This sets #BM_ELEM_TAG which is used in tool code (e.g. #84426). * we could add a low-level API flag for this, see #BM_ELEM_API_FLAG_ENABLE and friends. */ static void bm_mesh_loops_calc_normals__single_threaded(BMesh *bm, @@ -1449,7 +1449,7 @@ static bool bm_mesh_loops_split_lnor_fans(BMesh *bm, /* We also have to check between last and first loops, * otherwise we may miss some sharp edges here! * This is just a simplified version of above while loop. - * See T45984. */ + * See #45984. */ loops = lnors_spacearr->lspacearr[i]->loops; if (loops && org_nor) { BMLoop *ml = static_cast(loops->link); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index a1842b598d5..c383237c1ae 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -414,7 +414,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, /* Collapse between 2 edges */ /* in this case we want to keep all faces and not join them, - * rather just get rid of the vertex - see bug T28645. */ + * rather just get rid of the vertex - see bug #28645. */ BMVert *tv = BM_edge_other_vert(e_kill, v_kill); if (tv) { BMEdge *e2 = bmesh_disk_edge_next(e_kill, v_kill); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 8b185b17a3a..13fde0e8cf4 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1235,7 +1235,7 @@ void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int l } #define EDGE_SHARE_VERT(e1, e2) \ - ((ELEM((e1)[0], (e2)[0], (e2)[1])) || (ELEM((e1)[1], (e2)[0], (e2)[1]))) + (ELEM((e1)[0], (e2)[0], (e2)[1]) || ELEM((e1)[1], (e2)[0], (e2)[1])) /* do line crossing tests */ for (i = 0, i_prev = f->len - 1; i < f->len; i_prev = i++) { diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c index 81793ee9995..b4cfeb43c8f 100644 --- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c +++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c @@ -472,7 +472,7 @@ bool BM_face_split_edgenet(BMesh *bm, } /* These arrays used to be stack memory, however they can be - * large for single faces with complex edge-nets, see: T65980. */ + * large for single faces with complex edge-nets, see: #65980. */ /* over-alloc (probably 2-4 is only used in most cases), for the biggest-fan */ edge_order = MEM_mallocN(sizeof(*edge_order) * edge_order_len, __func__); @@ -501,7 +501,7 @@ bool BM_face_split_edgenet(BMesh *bm, * however in rare cases verts are added multiple times to the queue, * that on its own is harmless but in _very_ rare cases, * the queue will overflow its maximum size, - * so we better be strict about this! see: T51539 */ + * so we better be strict about this! see: #51539 */ for (i = 0; i < edge_net_len; i++) { BM_ELEM_API_FLAG_ENABLE(edge_net[i], EDGE_NET); @@ -706,7 +706,7 @@ BLI_INLINE bool edge_isect_verts_point_2d(const BMEdge *e, float r_isect[2]) { /* This bias seems like it could be too large, - * mostly its not needed, see T52329 for example where it is. */ + * mostly its not needed, see #52329 for example where it is. */ const float endpoint_bias = 1e-4f; return ((isect_seg_seg_v2_point_ex( v_a->co, v_b->co, e->v1->co, e->v2->co, endpoint_bias, r_isect) == 1) && @@ -1159,7 +1159,7 @@ static BMVert *bm_face_split_edgenet_partial_connect(BMesh *bm, BMVert *v_delimi BLI_assert(v_delimit->e != NULL); - /* Degenerate, avoid eternal loop, see: T59074. */ + /* Degenerate, avoid eternal loop, see: #59074. */ # if 0 BLI_assert(v_split->e != NULL); # else @@ -1481,7 +1481,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm, /* Now create bvh tree * * Note that a large epsilon is used because meshes with dimensions of around 100+ need it. - * see T52329. */ + * see #52329. */ BVHTree *bvhtree = BLI_bvhtree_new(edge_arr_len, 1e-4f, 8, 8); for (uint i = 0; i < edge_arr_len; i++) { const float e_cos[2][3] = { @@ -1633,7 +1633,7 @@ finally: struct TempVertPair *tvp = temp_vert_pairs.list; do { /* its _very_ unlikely the edge exists, - * however splicing may cause this. see: T48012 */ + * however splicing may cause this. see: #48012 */ if (!BM_edge_exists(tvp->v_orig, tvp->v_temp)) { BM_vert_splice(bm, tvp->v_orig, tvp->v_temp); } diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c index 643b5750d76..e471d4804be 100644 --- a/source/blender/bmesh/intern/bmesh_query.c +++ b/source/blender/bmesh/intern/bmesh_query.c @@ -2042,7 +2042,7 @@ bool BM_face_is_normal_valid(const BMFace *f) /** * Use to accumulate volume calculation for faces with consistent winding. * - * Use double precision since this is prone to float precision error, see T73295. + * Use double precision since this is prone to float precision error, see #73295. */ static double bm_mesh_calc_volume_face(const BMFace *f) { diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h index 2aff7e4bc6b..5908d639db2 100644 --- a/source/blender/bmesh/intern/bmesh_query.h +++ b/source/blender/bmesh/intern/bmesh_query.h @@ -762,7 +762,7 @@ int BM_mesh_calc_edge_groups(BMesh *bm, * * While we could call this, then create vertex & face arrays, * it requires looping over geometry connectivity twice, - * this slows down edit-mesh separate by loose parts, see: T70864. + * this slows down edit-mesh separate by loose parts, see: #70864. */ int BM_mesh_calc_edge_groups_as_arrays(BMesh *bm, BMVert **verts, diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index 2984ea93cb7..19a7c04a22a 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -930,7 +930,7 @@ static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data) */ if ((lwalk->is_boundary == false) && /* Without checking the face count, the 3 edges could be this edge - * plus two boundary edges (which would not be stepped over), see T84906. */ + * plus two boundary edges (which would not be stepped over), see #84906. */ ((vert_edge_count[0] == 3 && vert_face_count[0] == 3) || (vert_edge_count[1] == 3 && vert_face_count[1] == 3))) { BMIter iter; diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c index b6520fb48b3..872557c6ca1 100644 --- a/source/blender/bmesh/operators/bmo_bridge.c +++ b/source/blender/bmesh/operators/bmo_bridge.c @@ -15,9 +15,9 @@ #include "intern/bmesh_operators_private.h" /* own include */ /** - * TODO(@campbellbarton): Many connected edge loops can cause an error attempting + * TODO(@ideasman42): Many connected edge loops can cause an error attempting * to create faces with duplicate vertices. While this needs to be investigated, - * it's simple enough to check for this case, see: T102232. + * it's simple enough to check for this case, see: #102232. */ #define USE_DUPLICATE_FACE_VERT_CHECK @@ -208,7 +208,7 @@ static void bridge_loop_pair(BMesh *bm, * the loops values of 'dir_a/b' is degenerate, * in this case compare the original directions * (before they were corrected by 'el_dir'), - * see: T43013 + * see: #43013 */ test_a = dir_a_orig; test_b = dir_b_orig; @@ -272,7 +272,7 @@ static void bridge_loop_pair(BMesh *bm, bool flip[2] = {false, false}; /* for direction aligned loops we can't rely on the directly we have, - * use the winding defined by the connected faces (see T48356). */ + * use the winding defined by the connected faces (see #48356). */ if (fabsf(dot_a) < eps) { if (winding_votes[0] < 0) { flip[0] = !flip[0]; diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 59a12db9241..6c784758d85 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -104,7 +104,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenera BMLoop *l_new; BMLoop *l_pair[2]; - /* Note that duplicate edges in this case is very unlikely but it can happen, see T70287. */ + /* Note that duplicate edges in this case is very unlikely but it can happen, see #70287. */ bool edge_exists = (BM_edge_exists(verts_pair[i][0], verts_pair[i][1]) != NULL); if ((l_pair[0] = BM_face_vert_share_loop(f, verts_pair[i][0])) && (l_pair[1] = BM_face_vert_share_loop(f, verts_pair[i][1]))) { diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index 26f1a9e626e..197ef3ce264 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -27,7 +27,7 @@ * - store a heap of paths which are being scanned (#PathContext.states). * - continuously search the shortest path in the heap. * - never step over the same element twice (tag elements as #ELE_TOUCHED). - * this avoids going into an eternal loop if there are many possible branches (see T45582). + * this avoids going into an eternal loop if there are many possible branches (see #45582). * - when running into a branch, create a new #PathLinkState state and add to the heap. * - when the target is reached, * finish - since none of the other paths can be shorter than the one just found. @@ -109,7 +109,7 @@ typedef struct PathLinkState { /* -------------------------------------------------------------------- */ /** \name Min Dist Dir Util * - * Simply getting the closest intersecting vert/edge is _not_ good enough. see T43792 + * Simply getting the closest intersecting vert/edge is _not_ good enough. see #43792 * we need to get the closest in both directions since the absolute closest may be a dead-end. * * Logic is simple: @@ -504,7 +504,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3]) project_plane_normalized_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir); /* Don't normalize before combining so as normals approach the direction, - * they have less effect (T46784). */ + * they have less effect (#46784). */ /* combine the normals */ /* for flipped faces */ diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index 9dba48a8961..15a5750fa29 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -19,7 +19,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) { - /* NOTE(@campbellbarton): doing the best thing here isn't always easy create vs dissolve, + /* NOTE(@ideasman42): doing the best thing here isn't always easy create vs dissolve, * its nice to support but it _really_ gives issues we might have to not call dissolve. */ BMOIter oiter; diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 1ed9d763e8c..07315fce139 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -113,7 +113,7 @@ static BMEdge *bmo_edge_copy(BMOperator *op, if (use_edge_flip_from_face) { /* Take winding from previous face (if we had one), - * otherwise extruding a duplicated edges gives bad normals, see: T62487. */ + * otherwise extruding a duplicated edges gives bad normals, see: #62487. */ if (BM_edge_is_boundary(e_src) && (e_src->l->v == e_src->v1)) { BM_edge_verts_swap(e_dst); } diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index 8083a06e0b5..11095edac02 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -215,7 +215,7 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) v4 = BM_vert_in_edge(edges2[i - 1], edges2[i]->v1) ? edges2[i]->v2 : edges2[i]->v1; } - /* if there is ever bow-tie quads between two edges the problem is here! T30367. */ + /* if there is ever bow-tie quads between two edges the problem is here! #30367. */ #if 0 normal_tri_v3(dvec1, v1->co, v2->co, v4->co); normal_tri_v3(dvec2, v1->co, v4->co, v3->co); diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 48d8cded95d..21b32d48711 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -367,7 +367,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) /* calculate verts to delete */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (v->e) { /* only deal with verts attached to geometry T33651. */ + if (v->e) { /* only deal with verts attached to geometry #33651. */ found = false; BM_ITER_ELEM (e, &viter, v, BM_EDGES_OF_VERT) { @@ -466,10 +466,10 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) BMVert *v1 = e->v1, *v2 = e->v2; /* The original edge was excluded, - * this would result in a standalone wire edge - see T30399. */ + * this would result in a standalone wire edge - see #30399. */ BM_edge_kill(bm, e); - /* kill standalone vertices from this edge - see T32341. */ + /* kill standalone vertices from this edge - see #32341. */ if (!v1->e) { BM_vert_kill(bm, v1); } @@ -480,7 +480,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) continue; } - /* skip creating face for excluded edges see T35503. */ + /* skip creating face for excluded edges see #35503. */ if (BMO_slot_map_contains(slot_edges_exclude, e)) { /* simply skip creating the face */ continue; diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c index e256e261eaa..9a2d297e36c 100644 --- a/source/blender/bmesh/operators/bmo_fill_grid.c +++ b/source/blender/bmesh/operators/bmo_fill_grid.c @@ -602,7 +602,7 @@ void bmo_grid_fill_exec(BMesh *bm, BMOperator *op) if (count != 2) { /* Note that this error message has been adjusted to make sense when called * from the operator 'MESH_OT_fill_grid' which has a 'prepare' pass which can - * extract two 'rail' loops from a single edge loop, see T72075. */ + * extract two 'rail' loops from a single edge loop, see #72075. */ BMO_error_raise(bm, op, BMO_ERROR_CANCEL, diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index f46b9158c45..1b2ab25d830 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -20,7 +20,7 @@ #include "intern/bmesh_operators_private.h" /* own include */ -/* Merge loop-data that diverges, see: T41445 */ +/* Merge loop-data that diverges, see: #41445 */ #define USE_LOOP_CUSTOMDATA_MERGE #define ELE_NEW 1 @@ -953,10 +953,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) is_mid = false; } - /* Disable since this gives odd results at times, see T39288. */ + /* Disable since this gives odd results at times, see #39288. */ #if 0 else if (compare_v3v3(f_a->no, f_b->no, 0.001f) == false) { - /* epsilon increased to fix T32329. */ + /* epsilon increased to fix #32329. */ /* faces don't touch, * just get cross product of their normals, its *good enough* diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index 70984ba10bd..1649aa7344a 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -1391,7 +1391,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) BMFace **side_faces = MEM_mallocN(sizeof(*side_faces) * side_faces_len, __func__); for (int i = 0; i < segs; i++) { - /* Calculate with higher precision, see: T87779. */ + /* Calculate with higher precision, see: #87779. */ float sin_phi, cos_phi; sin_cos_from_fraction(i, segs, &sin_phi, &cos_phi); diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c index 575a88331da..d19530edae6 100644 --- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c +++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c @@ -462,7 +462,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op) i = m_vertex_id; if ((sys->zerola[i] == false) && /* Non zero check is to account for vertices that aren't connected to a selected face. - * Without this wire edges become `nan`, see T89214. */ + * Without this wire edges become `nan`, see #89214. */ (sys->ring_areas[i] != 0.0f)) { w = sys->vweights[i] * sys->ring_areas[i]; sys->vweights[i] = (w == 0.0f) ? 0.0f : -lambda_factor / (4.0f * w); diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 6b2df40549d..72509dd4f6c 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -97,7 +97,7 @@ typedef struct SubDPattern { #define ELE_INNER 8 #define ELE_SPLIT 16 -/* see bug T32665, 0.00005 means a we get face splits at a little under 1.0 degrees */ +/* see bug #32665, 0.00005 means a we get face splits at a little under 1.0 degrees */ #define FLT_FACE_SPLIT_EPSILON 0.00005f /* @@ -1062,7 +1062,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) matched = 1; for (j = 0; j < pat->len; j++) { a = (j + i) % pat->len; - if ((!!BMO_edge_flag_test(bm, edges[a], SUBD_SPLIT)) != (!!pat->seledges[j])) { + if (!!BMO_edge_flag_test(bm, edges[a], SUBD_SPLIT) != (!!pat->seledges[j])) { matched = 0; break; } @@ -1095,7 +1095,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) matched = 1; for (b = 0; b < pat->len; b++) { j = (b + a) % pat->len; - if ((!!BMO_edge_flag_test(bm, edges[j], SUBD_SPLIT)) != (!!pat->seledges[b])) { + if (!!BMO_edge_flag_test(bm, edges[j], SUBD_SPLIT) != (!!pat->seledges[b])) { matched = 0; break; } @@ -1202,7 +1202,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) for (j = 0; j < numcuts; j++) { bool ok = true; - /* Check for special case, see: T32500. + /* Check for special case, see: #32500. * This edge pair could be used by more than one face, * in this case it used to (2.63), split both faces along the same verts * while it could be calculated which face should do the split, diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index 6f41da7bb43..474b8ad6263 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -1095,7 +1095,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op) BMFace *f; BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) { - /* could support ngons, other areas would need updating too, see T48926. */ + /* could support ngons, other areas would need updating too, see #48926. */ if ((f->len <= 4) && !BMO_face_flag_test(bm, f, FACE_OUT)) { BMIter liter; BMLoop *l; diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index 13afff41263..1cba81cc208 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -72,7 +72,7 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) "use_shapekey"); /* important 'flip_multires' is disabled, - * otherwise multi-res data will be reversed, see: T47788 */ + * otherwise multi-res data will be reversed, see: #47788 */ BMO_op_callf(bm, op->flag, "reverse_faces faces=%S", &op_dupe, "geom.out"); /* Weld verts */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 36222ffa1f0..5118eb792d5 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1351,7 +1351,7 @@ static void offset_meet(BevelParams *bp, /* Special case: e1 and e2 are parallel; put offset point perp to both, from v. * need to find a suitable plane. * This code used to just use offset and dir1, but that makes for visible errors - * on a circle with > 200 sides, which trips this "nearly perp" code (see T61214). + * on a circle with > 200 sides, which trips this "nearly perp" code (see #61214). * so use the average of the two, and the offset formula for angle bisector. * If offsets are different, we're out of luck: * Use the max of the two (so get consistent looking results if the same situation @@ -1504,9 +1504,9 @@ static void offset_meet(BevelParams *bp, } } -/* This was changed from 0.25f to fix bug T86768. - * Original bug T44961 remains fixed with this value. - * Update: changed again from 0.0001f to fix bug T95335. +/* This was changed from 0.25f to fix bug #86768. + * Original bug #44961 remains fixed with this value. + * Update: changed again from 0.0001f to fix bug #95335. * Original two bugs remained fixed. */ #define BEVEL_GOOD_ANGLE 0.1f @@ -2265,7 +2265,7 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin co[2] = z; } -#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) (BM_elem_flag_test(eh->e, flag)) +#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) BM_elem_flag_test(eh->e, flag) static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) { diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 1ea799f64e0..082c5821404 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -41,14 +41,14 @@ /** if the cost from #BLI_quadric_evaluate is 'noise', fallback to topology */ #define USE_TOPOLOGY_FALLBACK #ifdef USE_TOPOLOGY_FALLBACK -/** cost is calculated with double precision, it's ok to use a very small epsilon, see T48154. */ +/** cost is calculated with double precision, it's ok to use a very small epsilon, see #48154. */ # define TOPOLOGY_FALLBACK_EPS 1e-12f #endif #define BOUNDARY_PRESERVE_WEIGHT 100.0f /** * Uses double precision, impacts behavior on near-flat surfaces, - * cane give issues with very small faces. 1e-2 is too big, see: T48154. + * cane give issues with very small faces. 1e-2 is too big, see: #48154. */ #define OPTIMIZE_EPS 1e-8 #define COST_INVALID FLT_MAX @@ -272,7 +272,7 @@ static void bm_decim_build_edge_cost_single(BMEdge *e, } /* NOTE: 'cost' shouldn't be negative but happens sometimes with small values. - * this can cause faces that make up a flat surface to over-collapse, see T37121. */ + * this can cause faces that make up a flat surface to over-collapse, see #37121. */ cost = fabsf(cost); #ifdef USE_TOPOLOGY_FALLBACK diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c index e15122a11e3..0a668342ab4 100644 --- a/source/blender/bmesh/tools/bmesh_intersect.c +++ b/source/blender/bmesh/tools/bmesh_intersect.c @@ -1068,7 +1068,7 @@ bool BM_mesh_intersect(BMesh *bm, /* For self intersection this can be useful, sometimes users generate geometry * where surfaces that seem disconnected happen to share an edge. * So when performing intersection calculation allow shared vertices, - * just not shared edges. See T75946. */ + * just not shared edges. See #75946. */ const bool isect_tri_tri_no_shared = (boolean_mode != BMESH_ISECT_BOOLEAN_NONE); int flag = BVH_OVERLAP_USE_THREADING | BVH_OVERLAP_RETURN_PAIRS; @@ -1250,7 +1250,7 @@ bool BM_mesh_intersect(BMesh *bm, /* It's possible the vertex to dissolve is an edge on an existing face * that doesn't divide the face, therefor the edges are not wire - * and shouldn't be handled here, see: T63787. */ + * and shouldn't be handled here, see: #63787. */ if (!BLI_gset_haskey(s.wire_edges, e_pair[0]) || !BLI_gset_haskey(s.wire_edges, e_pair[1])) { continue; } @@ -1638,7 +1638,7 @@ bool BM_mesh_intersect(BMesh *bm, BLI_memarena_free(s.mem_arena); /* It's unlikely the selection history is useful at this point, - * if this is not called this array would need to be validated, see: T86799. */ + * if this is not called this array would need to be validated, see: #86799. */ BM_select_history_clear(bm); return (has_edit_isect || has_edit_boolean); diff --git a/source/blender/bmesh/tools/bmesh_path_region.c b/source/blender/bmesh/tools/bmesh_path_region.c index a90bf87ebb0..5b86b06aa50 100644 --- a/source/blender/bmesh/tools/bmesh_path_region.c +++ b/source/blender/bmesh/tools/bmesh_path_region.c @@ -23,7 +23,7 @@ * * \note Regarding manifold edge stepping: #BM_vert_is_edge_pair_manifold usage. * Logic to skip a chain of vertices is not applied at boundaries because it gives - * strange behavior from a user perspective especially with boundary quads, see: T52701 + * strange behavior from a user perspective especially with boundary quads, see: #52701 * * Restrict walking over a vertex chain to cases where the edges share the same faces. * This is more typical of what a user would consider a vertex chain. diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.c b/source/blender/bmesh/tools/bmesh_path_region_uv.c index 17812fe3bdd..25637fae949 100644 --- a/source/blender/bmesh/tools/bmesh_path_region_uv.c +++ b/source/blender/bmesh/tools/bmesh_path_region_uv.c @@ -27,7 +27,7 @@ * * \note Regarding manifold edge stepping: #BM_vert_is_edge_pair_manifold usage. * Logic to skip a chain of vertices is not applied at boundaries because it gives - * strange behavior from a user perspective especially with boundary quads, see: T52701 + * strange behavior from a user perspective especially with boundary quads, see: #52701 * * Restrict walking over a vertex chain to cases where the edges share the same faces. * This is more typical of what a user would consider a vertex chain. diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cc b/source/blender/compositor/nodes/COM_BokehBlurNode.cc index ebdc82b0d19..7d850915ada 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cc +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cc @@ -45,7 +45,7 @@ void BokehBlurNode::convert_to_operations(NodeConverter &converter, converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); /* NOTE: on the bokeh blur operation the sockets are switched. - * for this reason the next two lines are correct. Fix for T43771. */ + * for this reason the next two lines are correct. Fix for #43771. */ converter.map_input_socket(get_input_socket(2), operation->get_input_socket(3)); converter.map_input_socket(get_input_socket(3), operation->get_input_socket(2)); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cc b/source/blender/compositor/nodes/COM_ImageNode.cc index a7cc6bf39df..0920f60979b 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cc +++ b/source/blender/compositor/nodes/COM_ImageNode.cc @@ -179,7 +179,7 @@ void ImageNode::convert_to_operations(NodeConverter &converter, } BKE_image_release_ibuf(image, ibuf, nullptr); - /* without this, multilayer that fail to load will crash blender T32490. */ + /* without this, multilayer that fail to load will crash blender #32490. */ if (is_multilayer_ok == false) { for (NodeOutput *output : get_output_sockets()) { converter.set_invalid_output(output); diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cc b/source/blender/compositor/operations/COM_CompositorOperation.cc index 1ff27607d09..587f661646a 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cc +++ b/source/blender/compositor/operations/COM_CompositorOperation.cc @@ -219,7 +219,7 @@ void CompositorOperation::determine_canvas(const rcti & /*preferred_area*/, rcti BKE_render_resolution(rd_, false, &width, &height); /* Check actual render resolution with cropping it may differ with cropped border.rendering - * Fix for T31777 Border Crop gives black (easy). */ + * Fix for #31777 Border Crop gives black (easy). */ Render *re = RE_GetSceneRender(scene_); if (re) { RenderResult *rr = RE_AcquireResultRead(re); diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc index 25d4b2d6a6c..14b92bdcbd1 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc @@ -71,14 +71,14 @@ void ConvertDepthToRadiusOperation::execute_pixel_sampled(float output[4], if (z != 0.0f) { float iZ = (1.0f / z); - /* bug T6656 part 2b, do not re-scale. */ + /* bug #6656 part 2b, do not re-scale. */ #if 0 bcrad = 0.5f * fabs(aperture * (dof_sp * (cam_invfdist - iZ) - 1.0f)); /* Scale crad back to original maximum and blend. */ crad->rect[px] = bcrad + wts->rect[px] * (scf * crad->rect[px] - bcrad); #endif radius = 0.5f * fabsf(aperture_ * (dof_sp_ * (inverse_focal_distance_ - iZ) - 1.0f)); - /* 'bug' T6615, limit minimum radius to 1 pixel, + /* 'bug' #6615, limit minimum radius to 1 pixel, * not really a solution, but somewhat mitigates the problem. */ if (radius < 0.0f) { radius = 0.0f; @@ -111,7 +111,7 @@ void ConvertDepthToRadiusOperation::update_memory_buffer_partial(MemoryBuffer *o const float inv_z = (1.0f / z); - /* Bug T6656 part 2b, do not re-scale. */ + /* Bug #6656 part 2b, do not re-scale. */ #if 0 bcrad = 0.5f * fabs(aperture * (dof_sp * (cam_invfdist - iZ) - 1.0f)); /* Scale crad back to original maximum and blend: @@ -119,7 +119,7 @@ void ConvertDepthToRadiusOperation::update_memory_buffer_partial(MemoryBuffer *o #endif const float radius = 0.5f * fabsf(aperture_ * (dof_sp_ * (inverse_focal_distance_ - inv_z) - 1.0f)); - /* Bug T6615, limit minimum radius to 1 pixel, + /* Bug #6615, limit minimum radius to 1 pixel, * not really a solution, but somewhat mitigates the problem. */ *it.out = CLAMPIS(radius, 0.0f, max_radius_); } diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cc b/source/blender/compositor/operations/COM_CurveBaseOperation.cc index e7cbf0d28d5..67e117e33eb 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.cc +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cc @@ -35,7 +35,7 @@ void CurveBaseOperation::deinit_execution() void CurveBaseOperation::set_curve_mapping(const CurveMapping *mapping) { - /* duplicate the curve to avoid glitches while drawing, see bug T32374. */ + /* duplicate the curve to avoid glitches while drawing, see bug #32374. */ if (curve_mapping_) { BKE_curvemapping_free(curve_mapping_); } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc index cc914239caf..b469e76b116 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cc +++ b/source/blender/compositor/operations/COM_ScaleOperation.cc @@ -7,7 +7,7 @@ namespace blender::compositor { #define USE_FORCE_BILINEAR -/* XXX(@campbellbarton): ignore input and use default from old compositor, +/* XXX(@ideasman42): ignore input and use default from old compositor, * could become an option like the transform node. * * NOTE: use bilinear because bicubic makes fuzzy even when not scaling at all (1:1) diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc index ba0e7eb21ac..b45b3e100e8 100644 --- a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc +++ b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc @@ -41,10 +41,10 @@ static float *parallel_reduction_dispatch(Context &context, GPUTexture *reduced_texture = context.texture_pool().acquire(reduced_size, format); GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH); - const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(texture_to_reduce, texture_image_unit); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(reduced_texture, image_unit); GPU_compute_dispatch(shader, reduced_size.x, reduced_size.y, 1); diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc index eac88b907b8..98e7b67dca7 100644 --- a/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc @@ -135,7 +135,7 @@ void MorphologicalDistanceFeatherWeights::compute_distance_falloffs(int type, in void MorphologicalDistanceFeatherWeights::bind_weights_as_texture(GPUShader *shader, const char *texture_name) const { - const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name); GPU_texture_bind(weights_texture_, texture_image_unit); } @@ -147,7 +147,7 @@ void MorphologicalDistanceFeatherWeights::unbind_weights_as_texture() const void MorphologicalDistanceFeatherWeights::bind_distance_falloffs_as_texture( GPUShader *shader, const char *texture_name) const { - const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name); GPU_texture_bind(distance_falloffs_texture_, texture_image_unit); } diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc index b3200d468c9..db4c0f777f2 100644 --- a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc @@ -103,7 +103,7 @@ SymmetricBlurWeights::~SymmetricBlurWeights() void SymmetricBlurWeights::bind_as_texture(GPUShader *shader, const char *texture_name) const { - const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name); GPU_texture_bind(texture_, texture_image_unit); } diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc index b8c47d5a5d0..07d45531921 100644 --- a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc @@ -81,7 +81,7 @@ SymmetricSeparableBlurWeights::~SymmetricSeparableBlurWeights() void SymmetricSeparableBlurWeights::bind_as_texture(GPUShader *shader, const char *texture_name) const { - const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name); GPU_texture_bind(texture_, texture_image_unit); } diff --git a/source/blender/compositor/realtime_compositor/intern/result.cc b/source/blender/compositor/realtime_compositor/intern/result.cc index e301aa6e0ed..902eede7dd7 100644 --- a/source/blender/compositor/realtime_compositor/intern/result.cc +++ b/source/blender/compositor/realtime_compositor/intern/result.cc @@ -82,7 +82,7 @@ void Result::bind_as_texture(GPUShader *shader, const char *texture_name) const /* Make sure any prior writes to the texture are reflected before reading from it. */ GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH); - const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name); GPU_texture_bind(texture_, texture_image_unit); } @@ -93,7 +93,7 @@ void Result::bind_as_image(GPUShader *shader, const char *image_name, bool read) GPU_memory_barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS); } - const int image_unit = GPU_shader_get_texture_binding(shader, image_name); + const int image_unit = GPU_shader_get_sampler_binding(shader, image_name); GPU_texture_image_bind(texture_, image_unit); } diff --git a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc index 4ac997db42b..b4976e5eff0 100644 --- a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc @@ -95,14 +95,14 @@ void ShaderOperation::bind_material_resources(GPUShader *shader) * no uniforms. */ GPUUniformBuf *ubo = GPU_material_uniform_buffer_get(material_); if (ubo) { - GPU_uniformbuf_bind(ubo, GPU_shader_get_uniform_block_binding(shader, GPU_UBO_BLOCK_NAME)); + GPU_uniformbuf_bind(ubo, GPU_shader_get_ubo_binding(shader, GPU_UBO_BLOCK_NAME)); } /* Bind color band textures needed by curve and ramp nodes. */ ListBase textures = GPU_material_textures(material_); LISTBASE_FOREACH (GPUMaterialTexture *, texture, &textures) { if (texture->colorband) { - const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture->sampler_name); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture->sampler_name); GPU_texture_bind(*texture->colorband, texture_image_unit); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0c5dfdf5ced..9559c8a9e8d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1831,7 +1831,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) * For the sake of making the code more generic/defensive, the relation * is added for any geometry type. * - * See T96289 for more info. */ + * See #96289 for more info. */ if (object != nullptr && OB_TYPE_IS_GEOMETRY(object->type)) { StringRef rna_path(dtar->rna_path); if (rna_path == "data" || rna_path.startswith("data.")) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc index 009b191b91e..c3bad9b92a9 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc @@ -197,7 +197,7 @@ void DepsgraphRelationBuilder::build_driver_relations(IDNode *id_node) const DriverDescriptor &driver_to = prefix_group[to_index]; Node *op_to = get_node(driver_to.depsgraph_key()); - /* Duplicate drivers can exist (see T78615), but cannot be distinguished by OperationKey + /* Duplicate drivers can exist (see #78615), but cannot be distinguished by OperationKey * and thus have the same depsgraph node. Relations between those drivers should not be * created. This not something that is expected to happen (both the UI and the Python API * prevent duplicate drivers), it did happen in a file and it is easy to deal with here. */ diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index b997ac14f99..60a68663bfa 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -61,7 +61,7 @@ void DEG_evaluate_on_refresh(Depsgraph *graph) * since the undo state is stored before updates from the frame change have been applied. * In this case reading back the undo state will behave as if no updates on frame change * is needed as the #Depsgraph.ctime & frame will match the values in the input scene. - * Use #ID_RECALC_FRAME_CHANGE to detect that recalculation is necessary. see: T66913. */ + * Use #ID_RECALC_FRAME_CHANGE to detect that recalculation is necessary. see: #66913. */ deg_graph->tag_time_source(); } diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 34df9a537e1..ab3d05e7fa7 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -356,7 +356,7 @@ void DEG_iterator_objects_end(BLI_Iterator *iter) DEGObjectIterData *data = (DEGObjectIterData *)iter->data; if (data != nullptr) { /* Force crash in case the iterator data is referenced and accessed down - * the line. (T51718) */ + * the line. (#51718) */ deg_invalidate_iterator_work_data(data); } } diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 3bdc33b8d01..aac5366d35a 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -388,7 +388,7 @@ void deg_evaluate_on_refresh(Depsgraph *graph) graph->debug.begin_graph_evaluation(); #ifdef WITH_PYTHON - /* Release the GIL so that Python drivers can be evaluated. See T91046. */ + /* Release the GIL so that Python drivers can be evaluated. See #91046. */ BPy_BEGIN_ALLOW_THREADS; #endif diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 4e07a7b173c..4d2a9a7e850 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -737,7 +737,7 @@ void update_id_after_copy(const Depsgraph *depsgraph, scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast(id_cow)); break; } - /* FIXME: This is a temporary fix to update the runtime pointers properly, see T96216. Should + /* FIXME: This is a temporary fix to update the runtime pointers properly, see #96216. Should * be removed at some point. */ case ID_GD: { bGPdata *gpd_cow = (bGPdata *)id_cow; diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 19bd2267db5..ce3d09e46d9 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -151,6 +151,7 @@ set(SRC engines/eevee_next/eevee_renderbuffers.cc engines/eevee_next/eevee_sampling.cc engines/eevee_next/eevee_shader.cc + engines/eevee_next/eevee_shadow.cc engines/eevee_next/eevee_sync.cc engines/eevee_next/eevee_velocity.cc engines/eevee_next/eevee_view.cc @@ -281,6 +282,7 @@ set(SRC engines/eevee_next/eevee_renderbuffers.hh engines/eevee_next/eevee_sampling.hh engines/eevee_next/eevee_shader.hh + engines/eevee_next/eevee_shadow.hh engines/eevee_next/eevee_sync.hh engines/eevee_next/eevee_velocity.hh engines/eevee_next/eevee_view.hh @@ -422,6 +424,7 @@ set(GLSL_SRC engines/eevee_next/shaders/eevee_camera_lib.glsl engines/eevee_next/shaders/eevee_colorspace_lib.glsl engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl + engines/eevee_next/shaders/eevee_transparency_lib.glsl engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl engines/eevee_next/shaders/eevee_depth_of_field_bokeh_lut_comp.glsl engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl @@ -462,10 +465,29 @@ set(GLSL_SRC engines/eevee_next/shaders/eevee_motion_blur_lib.glsl engines/eevee_next/shaders/eevee_nodetree_lib.glsl engines/eevee_next/shaders/eevee_sampling_lib.glsl + engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl + engines/eevee_next/shaders/eevee_shadow_lib.glsl + engines/eevee_next/shaders/eevee_shadow_page_allocate_comp.glsl + engines/eevee_next/shaders/eevee_shadow_page_clear_comp.glsl + engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl + engines/eevee_next/shaders/eevee_shadow_page_free_comp.glsl + engines/eevee_next/shaders/eevee_shadow_page_mask_comp.glsl + engines/eevee_next/shaders/eevee_shadow_page_ops_lib.glsl + engines/eevee_next/shaders/eevee_shadow_tag_update_comp.glsl + engines/eevee_next/shaders/eevee_shadow_tag_usage_comp.glsl + engines/eevee_next/shaders/eevee_shadow_tag_usage_frag.glsl + engines/eevee_next/shaders/eevee_shadow_tag_usage_lib.glsl + engines/eevee_next/shaders/eevee_shadow_tag_usage_vert.glsl + engines/eevee_next/shaders/eevee_shadow_test.glsl + engines/eevee_next/shaders/eevee_shadow_tilemap_bounds_comp.glsl + engines/eevee_next/shaders/eevee_shadow_tilemap_finalize_comp.glsl + engines/eevee_next/shaders/eevee_shadow_tilemap_init_comp.glsl + engines/eevee_next/shaders/eevee_shadow_tilemap_lib.glsl engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl engines/eevee_next/shaders/eevee_surf_depth_frag.glsl engines/eevee_next/shaders/eevee_surf_forward_frag.glsl engines/eevee_next/shaders/eevee_surf_lib.glsl + engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl engines/eevee_next/shaders/eevee_surf_world_frag.glsl engines/eevee_next/shaders/eevee_velocity_lib.glsl @@ -797,6 +819,7 @@ if(WITH_GTESTS) set(TEST_SRC tests/draw_pass_test.cc tests/draw_testing.cc + tests/eevee_test.cc tests/shaders_test.cc tests/draw_testing.hh diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index e8c2dc259fc..8270367c3e6 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -180,7 +180,7 @@ static void basic_cache_populate(void *vedata, Object *ob) DRW_object_axis_orthogonal_to_view(ob, flat_axis)); if (is_flat_object_viewed_from_side) { - /* Avoid losing flat objects when in ortho views (see T56549) */ + /* Avoid losing flat objects when in ortho views (see #56549) */ struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob); if (geom) { DRW_shgroup_call(stl->g_data->depth_shgrp[do_in_front], geom, ob); diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index 1a1e3b80bad..3d041f32bf3 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -126,7 +126,7 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData * /* Assumes that all instances have the same object pointer. This is currently the case because * instance objects are temporary objects on the stack. */ /* WORKAROUND: Duplicate object key for particle system (hairs) to be able to store dupli offset - * matrix along with the emitter obmat. (see T97380) */ + * matrix along with the emitter obmat. (see #97380) */ key.ob = (void *)((char *)ob + is_psys); DupliObject *dup = DRW_object_get_dupli(ob); if (dup) { diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 0e1cc82797a..68e61235bea 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -93,7 +93,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, effects->enabled_effects |= EEVEE_screen_raytrace_init(sldata, vedata); /* Update matrices here because EEVEE_screen_raytrace_init can have reset the - * taa_current_sample. (See T66811) */ + * taa_current_sample. (See #66811) */ EEVEE_temporal_sampling_update_matrices(vedata); EEVEE_volumes_init(sldata, vedata); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 9f70a2dd72b..fd11839d5b3 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -399,7 +399,7 @@ static void eevee_id_world_update(void *vedata, World *wo) LightCache *lcache = stl->g_data->light_cache; if (ELEM(lcache, NULL, stl->lookdev_lightcache)) { - /* Avoid Lookdev viewport clearing the update flag (see T67741). */ + /* Avoid Lookdev viewport clearing the update flag (see #67741). */ return; } diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index b28189973da..84b4d6dda7a 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -530,7 +530,7 @@ static void write_lightcache_texture(BlendWriter *writer, LightCacheTexture *tex } /* FIXME: We can't save more than what 32bit systems can handle. - * The solution would be to split the texture but it is too late for 2.90. (see T78529) */ + * The solution would be to split the texture but it is too late for 2.90. (see #78529) */ if (data_size < INT_MAX) { BLO_write_raw(writer, data_size, tex->data); } diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index e6a3db83951..4c9a98a9e9e 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -507,7 +507,7 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata) if (!GPU_batch_vertbuf_has(batch, vbo)) { /* Currently, the code assumes that all objects that share the same mesh in the * current frame also share the same mesh on other frames. */ - GPU_batch_vertbuf_add_ex(batch, vbo, false); + GPU_batch_vertbuf_add(batch, vbo, false); } } } diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index c8e571ee9d4..136f14afbb3 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -607,7 +607,7 @@ typedef struct EEVEE_MotionBlurData { typedef struct EEVEE_ObjectKey { /** Object or source object for duplis. */ /** WORKAROUND: The pointer is different for particle systems and do not point to the real - * object. (See T97380) */ + * object. (See #97380) */ void *ob; /** Parent object for duplis */ struct Object *parent; @@ -988,7 +988,7 @@ typedef struct EEVEE_PrivateData { float camtexcofac[4]; float size_orig[2]; - /* Cached original camera when rendering for motion blur (see T79637). */ + /* Cached original camera when rendering for motion blur (see #79637). */ struct Object *cam_original_ob; /* Mist Settings */ diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 1d18056e175..6f47007c3c5 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -206,7 +206,7 @@ void EEVEE_render_cache(void *vedata, /* Don't print dupli objects as this can be very verbose and * increase the render time on Windows because of slow windows term. - * (see T59649) */ + * (see #59649) */ if (engine && (ob->base_flag & BASE_FROM_DUPLI) == 0) { char info[42]; BLI_snprintf(info, sizeof(info), "Syncing %s", ob->id.name + 2); @@ -571,7 +571,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl EEVEE_temporal_sampling_reset(vedata); stl->effects->ssr_was_valid_double_buffer = stl->g_data->valid_double_buffer; } - /* Don't print every samples as it can lead to bad performance. (see T59649) */ + /* Don't print every samples as it can lead to bad performance. (see #59649) */ else if ((render_samples % 25) == 0 || (render_samples + 1) == tot_sample) { char info[42]; BLI_snprintf( diff --git a/source/blender/draw/engines/eevee/eevee_sampling.c b/source/blender/draw/engines/eevee/eevee_sampling.c index 34d3cd74b36..d47a99f7c4f 100644 --- a/source/blender/draw/engines/eevee/eevee_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_sampling.c @@ -17,7 +17,7 @@ void EEVEE_sample_ball(int sample_ofs, float radius, float rsample[3]) BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point); - /* De-correlate AA and shadow samples. (see T68594) */ + /* De-correlate AA and shadow samples. (see #68594) */ ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0); ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0); ht_point[2] = fmod(ht_point[2] * 1151.0, 1.0); @@ -48,7 +48,7 @@ void EEVEE_sample_rectangle(int sample_ofs, BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point); - /* De-correlate AA and shadow samples. (see T68594) */ + /* De-correlate AA and shadow samples. (see #68594) */ ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0); ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0); @@ -74,7 +74,7 @@ void EEVEE_sample_ellipse(int sample_ofs, BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point); - /* Decorrelate AA and shadow samples. (see T68594) */ + /* Decorrelate AA and shadow samples. (see #68594) */ ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0); ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0); @@ -98,7 +98,7 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]) BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point); - /* Decorrelate AA and shadow samples. (see T68594) */ + /* Decorrelate AA and shadow samples. (see #68594) */ ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0); ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0); ht_point[2] = fmod(ht_point[2] * 1151.0, 1.0); diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 5644fc6f1f4..4c5b6ae5f15 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -281,7 +281,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data effects->taa_total_sample = 1; } - /* Motion blur steps could reset the sampling when camera is animated (see T79970). */ + /* Motion blur steps could reset the sampling when camera is animated (see #79970). */ if (!DRW_state_is_scene_render()) { DRW_view_persmat_get(NULL, persmat, false); view_is_valid = view_is_valid && compare_m4m4(persmat, effects->prev_drw_persmat, FLT_MIN); @@ -309,7 +309,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data } else { const bool all_shaders_compiled = stl->g_data->queued_shaders_count_prev == 0; - /* Fix Texture painting (see T79370) and shader compilation (see T78520). */ + /* Fix Texture painting (see #79370) and shader compilation (see #78520). */ if (DRW_state_is_navigating() || !all_shaders_compiled) { effects->taa_current_sample = 1; } diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 872696a8b7c..72ea7a7f203 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -300,7 +300,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, float size[3]; mat4_to_size(size, ob->object_to_world); - /* Check if any of the axes have 0 length. (see T69070) */ + /* Check if any of the axes have 0 length. (see #69070) */ const float epsilon = 1e-8f; if ((size[0] < epsilon) || (size[1] < epsilon) || (size[2] < epsilon)) { return; diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index e0e8975369a..32748a71038 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -295,7 +295,7 @@ void occlusion_eval(OcclusionData data, bent_normal = N; } else { - /* NOTE: using pow(visibility, 6.0) produces NaN (see T87369). */ + /* NOTE: using pow(visibility, 6.0) produces NaN (see #87369). */ float tmp = saturate(pow6(visibility)); bent_normal = normalize(mix(bent_normal, N, tmp)); } diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl index 574b24b3650..965b11c8e2e 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl @@ -92,7 +92,7 @@ void closure_Diffuse_eval_end(ClosureInputDiffuse cl_in, { cl_out.radiance = render_pass_diffuse_mask(cl_out.radiance); #if defined(DEPTH_SHADER) || defined(WORLD_BACKGROUND) - /* This makes shader resources become unused and avoid issues with samplers. (see T59747) */ + /* This makes shader resources become unused and avoid issues with samplers. (see #59747) */ cl_out.radiance = vec3(0.0); return; #endif diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl index 0deaf4054d2..83b3fafddcb 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl @@ -147,7 +147,7 @@ void closure_Glossy_eval_end(ClosureInputGlossy cl_in, { cl_out.radiance = render_pass_glossy_mask(cl_out.radiance); #if defined(DEPTH_SHADER) || defined(WORLD_BACKGROUND) - /* This makes shader resources become unused and avoid issues with samplers. (see T59747) */ + /* This makes shader resources become unused and avoid issues with samplers. (see #59747) */ cl_out.radiance = vec3(0.0); return; #endif diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_refraction_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_refraction_lib.glsl index 5c6769b185a..400480564dd 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_refraction_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_refraction_lib.glsl @@ -127,7 +127,7 @@ void closure_Refraction_eval_end(ClosureInputRefraction cl_in, { cl_out.radiance = render_pass_glossy_mask(cl_out.radiance); #if defined(DEPTH_SHADER) || defined(WORLD_BACKGROUND) - /* This makes shader resources become unused and avoid issues with samplers. (see T59747) */ + /* This makes shader resources become unused and avoid issues with samplers. (see #59747) */ cl_out.radiance = vec3(0.0); return; #endif diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl index 89a6f10e634..2702b867ef6 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl @@ -73,7 +73,7 @@ void closure_Translucent_eval_end(ClosureInputTranslucent cl_in, { cl_out.radiance = render_pass_diffuse_mask(cl_out.radiance); #if defined(DEPTH_SHADER) || defined(WORLD_BACKGROUND) - /* This makes shader resources become unused and avoid issues with samplers. (see T59747) */ + /* This makes shader resources become unused and avoid issues with samplers. (see #59747) */ cl_out.radiance = vec3(0.0); return; #endif diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl index 2a5d456feff..32eaa85408a 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl @@ -19,7 +19,7 @@ void main() #else /* NOTE(@fclem): textureSize() does not work the same on all implementations - * when changing the min and max texture levels. Use uniform instead (see T87801). */ + * when changing the min and max texture levels. Use uniform instead (see #87801). */ vec2 uvs = gl_FragCoord.xy * texelSize; vec4 ofs = texelSize.xyxy * vec4(0.75, 0.75, -0.75, -0.75); uvs *= 2.0; diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl index 9570e542d9e..1f81bc30b17 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -35,7 +35,7 @@ void main() float val = sampleLowerMip(uv); #else /* NOTE(@fclem): textureSize() does not work the same on all implementations - * when changing the min and max texture levels. Use uniform instead (see T87801). */ + * when changing the min and max texture levels. Use uniform instead (see #87801). */ vec2 uv = texel * 2.0 * texelSize; vec4 samp; diff --git a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl index 3e7181f2274..ef89bd92f53 100644 --- a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl @@ -49,7 +49,7 @@ vec3 solve_cubic(vec4 coefs) /* Discriminant */ float discr = dot(vec2(4.0 * delta.x, -delta.y), delta.zy); - /* Clamping avoid NaN output on some platform. (see T67060) */ + /* Clamping avoid NaN output on some platform. (see #67060) */ float sqrt_discr = sqrt(clamp(discr, 0.0, FLT_MAX)); vec2 xlc, xsc; diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl index bf105bd907b..e5fb19c9da7 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl @@ -145,7 +145,7 @@ void main() /* Only supported attrib for world/background shaders. */ vec3 attr_load_orco(vec4 orco) { - /* Retain precision better than g_data.P (see T99128). */ + /* Retain precision better than g_data.P (see #99128). */ return -normal_view_to_world(viewCameraVec(viewPosition)); } /* Unsupported. */ diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl index 82817059854..8f4a80ce6c3 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl @@ -52,7 +52,7 @@ void main() float ray_len = orig_ray_len * cell_depth; /* Emission does not work of there is no extinction because - * Tr evaluates to 1.0 leading to Lscat = 0.0. (See T65771) */ + * Tr evaluates to 1.0 leading to Lscat = 0.0. (See #65771) */ s_extinction = max(vec3(1e-7) * step(1e-5, Lscat), s_extinction); /* Evaluate Scattering */ diff --git a/source/blender/draw/engines/eevee_next/eevee_camera.cc b/source/blender/draw/engines/eevee_next/eevee_camera.cc index c493952f194..2526f2875d0 100644 --- a/source/blender/draw/engines/eevee_next/eevee_camera.cc +++ b/source/blender/draw/engines/eevee_next/eevee_camera.cc @@ -135,8 +135,9 @@ void Camera::sync() #endif } else if (inst_.drw_view) { - data.clip_near = DRW_view_near_distance_get(inst_.drw_view); - data.clip_far = DRW_view_far_distance_get(inst_.drw_view); + /* \note: Follow camera parameters where distances are positive in front of the camera. */ + data.clip_near = -DRW_view_near_distance_get(inst_.drw_view); + data.clip_far = -DRW_view_far_distance_get(inst_.drw_view); data.fisheye_fov = data.fisheye_lens = -1.0f; data.equirect_bias = float2(0.0f); data.equirect_scale = float2(0.0f); @@ -144,6 +145,57 @@ void Camera::sync() data_.initialized = true; data_.push_update(); + + update_bounds(); +} + +void Camera::update_bounds() +{ + float left, right, bottom, top, near, far; + projmat_dimensions(data_.winmat.ptr(), &left, &right, &bottom, &top, &near, &far); + + BoundBox bbox; + bbox.vec[0][2] = bbox.vec[3][2] = bbox.vec[7][2] = bbox.vec[4][2] = -near; + bbox.vec[0][0] = bbox.vec[3][0] = left; + bbox.vec[4][0] = bbox.vec[7][0] = right; + bbox.vec[0][1] = bbox.vec[4][1] = bottom; + bbox.vec[7][1] = bbox.vec[3][1] = top; + + /* Get the coordinates of the far plane. */ + if (!this->is_orthographic()) { + float sca_far = far / near; + left *= sca_far; + right *= sca_far; + bottom *= sca_far; + top *= sca_far; + } + + bbox.vec[1][2] = bbox.vec[2][2] = bbox.vec[6][2] = bbox.vec[5][2] = -far; + bbox.vec[1][0] = bbox.vec[2][0] = left; + bbox.vec[6][0] = bbox.vec[5][0] = right; + bbox.vec[1][1] = bbox.vec[5][1] = bottom; + bbox.vec[2][1] = bbox.vec[6][1] = top; + + bound_sphere.center = {0.0f, 0.0f, 0.0f}; + bound_sphere.radius = 0.0f; + + for (auto i : IndexRange(8)) { + bound_sphere.center += float3(bbox.vec[i]); + } + bound_sphere.center /= 8.0f; + for (auto i : IndexRange(8)) { + float dist_sqr = math::distance_squared(bound_sphere.center, float3(bbox.vec[i])); + bound_sphere.radius = max_ff(bound_sphere.radius, dist_sqr); + } + bound_sphere.radius = sqrtf(bound_sphere.radius); + + /* Transform into world space. */ + bound_sphere.center = math::transform_point(data_.viewinv, bound_sphere.center); + + /* Compute diagonal length. */ + float2 p0 = float2(bbox.vec[0]) / (this->is_perspective() ? bbox.vec[0][2] : 1.0f); + float2 p1 = float2(bbox.vec[7]) / (this->is_perspective() ? bbox.vec[7][2] : 1.0f); + data_.screen_diagonal_length = math::distance(p0, p1); } /** \} */ diff --git a/source/blender/draw/engines/eevee_next/eevee_camera.hh b/source/blender/draw/engines/eevee_next/eevee_camera.hh index 86a71b179a2..10ea766a0a5 100644 --- a/source/blender/draw/engines/eevee_next/eevee_camera.hh +++ b/source/blender/draw/engines/eevee_next/eevee_camera.hh @@ -94,6 +94,11 @@ class Camera { CameraDataBuf data_; + struct { + float3 center; + float radius; + } bound_sphere; + public: Camera(Instance &inst) : inst_(inst){}; ~Camera(){}; @@ -133,6 +138,17 @@ class Camera { { return data_.viewinv.z_axis(); } + const float3 &bound_center() const + { + return bound_sphere.center; + } + const float &bound_radius() const + { + return bound_sphere.radius; + } + + private: + void update_bounds(); }; /** \} */ diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index 55d3921e39b..72470ab7060 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -32,15 +32,29 @@ * SHADOW_TILEMAP_RES max is 32 because of the shared bitmaps used for LOD tagging. * It is also limited by the maximum thread group size (1024). */ -#define SHADOW_TILEMAP_RES 16 -#define SHADOW_TILEMAP_LOD 4 /* LOG2(SHADOW_TILEMAP_RES) */ +#define SHADOW_TILEMAP_RES 32 +#define SHADOW_TILEMAP_LOD 5 /* LOG2(SHADOW_TILEMAP_RES) */ +#define SHADOW_TILEMAP_LOD0_LEN ((SHADOW_TILEMAP_RES / 1) * (SHADOW_TILEMAP_RES / 1)) +#define SHADOW_TILEMAP_LOD1_LEN ((SHADOW_TILEMAP_RES / 2) * (SHADOW_TILEMAP_RES / 2)) +#define SHADOW_TILEMAP_LOD2_LEN ((SHADOW_TILEMAP_RES / 4) * (SHADOW_TILEMAP_RES / 4)) +#define SHADOW_TILEMAP_LOD3_LEN ((SHADOW_TILEMAP_RES / 8) * (SHADOW_TILEMAP_RES / 8)) +#define SHADOW_TILEMAP_LOD4_LEN ((SHADOW_TILEMAP_RES / 16) * (SHADOW_TILEMAP_RES / 16)) +#define SHADOW_TILEMAP_LOD5_LEN ((SHADOW_TILEMAP_RES / 32) * (SHADOW_TILEMAP_RES / 32)) #define SHADOW_TILEMAP_PER_ROW 64 -#define SHADOW_PAGE_COPY_GROUP_SIZE 32 -#define SHADOW_DEPTH_SCAN_GROUP_SIZE 32 +#define SHADOW_TILEDATA_PER_TILEMAP \ + (SHADOW_TILEMAP_LOD0_LEN + SHADOW_TILEMAP_LOD1_LEN + SHADOW_TILEMAP_LOD2_LEN + \ + SHADOW_TILEMAP_LOD3_LEN + SHADOW_TILEMAP_LOD4_LEN + SHADOW_TILEMAP_LOD5_LEN) +#define SHADOW_PAGE_CLEAR_GROUP_SIZE 32 +#define SHADOW_PAGE_RES 256 +#define SHADOW_DEPTH_SCAN_GROUP_SIZE 8 #define SHADOW_AABB_TAG_GROUP_SIZE 64 #define SHADOW_MAX_TILEMAP 4096 +#define SHADOW_MAX_TILE (SHADOW_MAX_TILEMAP * SHADOW_TILEDATA_PER_TILEMAP) #define SHADOW_MAX_PAGE 4096 #define SHADOW_PAGE_PER_ROW 64 +#define SHADOW_ATLAS_SLOT 5 +#define SHADOW_BOUNDS_GROUP_SIZE 64 +#define SHADOW_VIEW_MAX 64 /* Must match DRW_VIEW_MAX. */ /* Ray-tracing. */ #define RAYTRACE_GROUP_SIZE 16 @@ -74,6 +88,11 @@ /* Resource bindings. */ /* Texture. */ +#define SHADOW_TILEMAPS_TEX_SLOT 12 +/* Only during surface shading. */ +#define SHADOW_ATLAS_TEX_SLOT 13 +/* Only during shadow rendering. */ +#define SHADOW_RENDER_MAP_SLOT 13 #define RBUFS_UTILITY_TEX_SLOT 14 /* Images. */ @@ -99,7 +118,10 @@ #define LIGHT_BUF_SLOT 1 #define LIGHT_ZBIN_BUF_SLOT 2 #define LIGHT_TILE_BUF_SLOT 3 +/* Only during surface shading. */ #define RBUFS_AOV_BUF_SLOT 5 +/* Only during shadow rendering. */ +#define SHADOW_PAGE_INFO_SLOT 5 #define SAMPLING_BUF_SLOT 6 #define CRYPTOMATTE_BUF_SLOT 7 diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 744b1611f37..f57e15bd422 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -67,6 +67,7 @@ void Instance::init(const int2 &output_res, film.init(output_res, output_rect); velocity.init(); depth_of_field.init(); + shadows.init(); motion_blur.init(); main_view.init(); } @@ -102,6 +103,7 @@ void Instance::begin_sync() materials.begin_sync(); velocity.begin_sync(); /* NOTE: Also syncs camera. */ lights.begin_sync(); + shadows.begin_sync(); cryptomatte.begin_sync(); gpencil_engine_enabled = false; @@ -197,6 +199,7 @@ void Instance::object_sync_render(void *instance_, void Instance::end_sync() { velocity.end_sync(); + shadows.end_sync(); /** \note: Needs to be before lights. */ lights.end_sync(); sampling.end_sync(); film.end_sync(); diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.hh b/source/blender/draw/engines/eevee_next/eevee_instance.hh index bc610cd0642..ba17289604c 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.hh +++ b/source/blender/draw/engines/eevee_next/eevee_instance.hh @@ -27,6 +27,7 @@ #include "eevee_renderbuffers.hh" #include "eevee_sampling.hh" #include "eevee_shader.hh" +#include "eevee_shadow.hh" #include "eevee_sync.hh" #include "eevee_view.hh" #include "eevee_world.hh" @@ -46,6 +47,7 @@ class Instance { SyncModule sync; MaterialModule materials; PipelineModule pipelines; + ShadowModule shadows; LightModule lights; VelocityModule velocity; MotionBlurModule motion_blur; @@ -89,6 +91,7 @@ class Instance { sync(*this), materials(*this), pipelines(*this), + shadows(*this), lights(*this), velocity(*this), motion_blur(*this), diff --git a/source/blender/draw/engines/eevee_next/eevee_light.cc b/source/blender/draw/engines/eevee_next/eevee_light.cc index 665042a44a5..2f9ffab425e 100644 --- a/source/blender/draw/engines/eevee_next/eevee_light.cc +++ b/source/blender/draw/engines/eevee_next/eevee_light.cc @@ -41,7 +41,7 @@ static eLightType to_light_type(short blender_light_type, short blender_area_typ /** \name Light Object * \{ */ -void Light::sync(/* ShadowModule &shadows , */ const Object *ob, float threshold) +void Light::sync(ShadowModule &shadows, const Object *ob, float threshold) { const ::Light *la = (const ::Light *)ob->data; float scale[3]; @@ -75,67 +75,49 @@ void Light::sync(/* ShadowModule &shadows , */ const Object *ob, float threshold this->volume_power = la->volume_fac * point_power; eLightType new_type = to_light_type(la->type, la->area_shape); - if (this->type != new_type) { - /* shadow_discard_safe(shadows); */ - this->type = new_type; + if (assign_if_different(this->type, new_type)) { + shadow_discard_safe(shadows); } -#if 0 if (la->mode & LA_SHADOW) { - if (la->type == LA_SUN) { - if (this->shadow_id == LIGHT_NO_SHADOW) { - this->shadow_id = shadows.directionals.alloc(); - } - - ShadowDirectional &shadow = shadows.directionals[this->shadow_id]; - shadow.sync(this->object_mat, la->bias * 0.05f, 1.0f); + shadow_ensure(shadows); + if (is_sun_light(this->type)) { + this->directional->sync(this->object_mat, 1.0f); } else { - float cone_aperture = DEG2RAD(360.0); - if (la->type == LA_SPOT) { - cone_aperture = min_ff(DEG2RAD(179.9), la->spotsize); - } - else if (la->type == LA_AREA) { - cone_aperture = DEG2RAD(179.9); - } - - if (this->shadow_id == LIGHT_NO_SHADOW) { - this->shadow_id = shadows.punctuals.alloc(); - } - - ShadowPunctual &shadow = shadows.punctuals[this->shadow_id]; - shadow.sync(this->type, - this->object_mat, - cone_aperture, - la->clipsta, - this->influence_radius_max, - la->bias * 0.05f); + this->punctual->sync( + this->type, this->object_mat, la->spotsize, la->clipsta, this->influence_radius_max); } } else { shadow_discard_safe(shadows); } -#endif this->initialized = true; } -#if 0 void Light::shadow_discard_safe(ShadowModule &shadows) { - if (shadow_id != LIGHT_NO_SHADOW) { - if (this->type != LIGHT_SUN) { - shadows.punctuals.free(shadow_id); - } - else { - shadows.directionals.free(shadow_id); - } - shadow_id = LIGHT_NO_SHADOW; + if (this->directional != nullptr) { + shadows.directional_pool.destruct(*directional); + this->directional = nullptr; + } + if (this->punctual != nullptr) { + shadows.punctual_pool.destruct(*punctual); + this->punctual = nullptr; + } +} + +void Light::shadow_ensure(ShadowModule &shadows) +{ + if (is_sun_light(this->type) && this->directional == nullptr) { + this->directional = &shadows.directional_pool.construct(shadows); + } + else if (this->punctual == nullptr) { + this->punctual = &shadows.punctual_pool.construct(shadows); } } -#endif -/* Returns attenuation radius inverted & squared for easy bound checking inside the shader. */ float Light::attenuation_radius_get(const ::Light *la, float light_threshold, float light_power) { if (la->type == LA_SUN) { @@ -265,6 +247,14 @@ void Light::debug_draw() /** \name LightModule * \{ */ +LightModule::~LightModule() +{ + /* WATCH: Destructor order. Expect shadow module to be destructed later. */ + for (Light &light : light_map_.values()) { + light.shadow_discard_safe(inst_.shadows); + } +}; + void LightModule::begin_sync() { use_scene_lights_ = inst_.use_scene_lights(); @@ -286,61 +276,44 @@ void LightModule::sync_light(const Object *ob, ObjectHandle &handle) Light &light = light_map_.lookup_or_add_default(handle.object_key); light.used = true; if (handle.recalc != 0 || !light.initialized) { - light.sync(/* inst_.shadows, */ ob, light_threshold_); + light.initialized = true; + light.sync(inst_.shadows, ob, light_threshold_); } - sun_lights_len_ += int(light.type == LIGHT_SUN); - local_lights_len_ += int(light.type != LIGHT_SUN); + sun_lights_len_ += int(is_sun_light(light.type)); + local_lights_len_ += int(!is_sun_light(light.type)); } void LightModule::end_sync() { - // ShadowModule &shadows = inst_.shadows; - /* NOTE: We resize this buffer before removing deleted lights. */ int lights_allocated = ceil_to_multiple_u(max_ii(light_map_.size(), 1), LIGHT_CHUNK); light_buf_.resize(lights_allocated); /* Track light deletion. */ - Vector deleted_keys; /* Indices inside GPU data array. */ int sun_lights_idx = 0; int local_lights_idx = sun_lights_len_; /* Fill GPU data with scene data. */ - for (auto item : light_map_.items()) { - Light &light = item.value; + auto it_end = light_map_.items().end(); + for (auto it = light_map_.items().begin(); it != it_end; ++it) { + Light &light = (*it).value; if (!light.used) { - /* Deleted light. */ - deleted_keys.append(item.key); - // light.shadow_discard_safe(shadows); + light_map_.remove(it); continue; } - int dst_idx = (light.type == LIGHT_SUN) ? sun_lights_idx++ : local_lights_idx++; + int dst_idx = is_sun_light(light.type) ? sun_lights_idx++ : local_lights_idx++; /* Put all light data into global data SSBO. */ light_buf_[dst_idx] = light; -#if 0 - if (light.shadow_id != LIGHT_NO_SHADOW) { - if (light.type == LIGHT_SUN) { - light_buf_[dst_idx].shadow_data = shadows.directionals[light.shadow_id]; - } - else { - light_buf_[dst_idx].shadow_data = shadows.punctuals[light.shadow_id]; - } - } -#endif /* Untag for next sync. */ light.used = false; } /* This scene data buffer is then immutable after this point. */ light_buf_.push_update(); - for (auto &key : deleted_keys) { - light_map_.remove(key); - } - /* Update sampling on deletion or un-hiding (use_scene_lights). */ if (assign_if_different(light_map_size_, light_map_.size())) { inst_.sampling.reset(); diff --git a/source/blender/draw/engines/eevee_next/eevee_light.hh b/source/blender/draw/engines/eevee_next/eevee_light.hh index ba7142f14a8..31988578c3b 100644 --- a/source/blender/draw/engines/eevee_next/eevee_light.hh +++ b/source/blender/draw/engines/eevee_next/eevee_light.hh @@ -34,25 +34,52 @@ namespace blender::eevee { class Instance; +class ShadowModule; /* -------------------------------------------------------------------- */ /** \name Light Object * \{ */ -struct Light : public LightData { +struct Light : public LightData, NonCopyable { public: bool initialized = false; bool used = false; + /** Pointers to source Shadow. Type depends on `LightData::type`. */ + ShadowDirectional *directional = nullptr; + ShadowPunctual *punctual = nullptr; + public: Light() { - shadow_id = LIGHT_NO_SHADOW; + /* Avoid valgrind warning. */ + this->type = LIGHT_SUN; } - void sync(/* ShadowModule &shadows, */ const Object *ob, float threshold); + /* Only used for debugging. */ +#ifndef NDEBUG + Light(Light &&other) + { + *static_cast(this) = other; + this->initialized = other.initialized; + this->used = other.used; + this->directional = other.directional; + this->punctual = other.punctual; + other.directional = nullptr; + other.punctual = nullptr; + } - // void shadow_discard_safe(ShadowModule &shadows); + ~Light() + { + BLI_assert(directional == nullptr); + BLI_assert(punctual == nullptr); + } +#endif + + void sync(ShadowModule &shadows, const Object *ob, float threshold); + + void shadow_ensure(ShadowModule &shadows); + void shadow_discard_safe(ShadowModule &shadows); void debug_draw(); @@ -73,7 +100,7 @@ struct Light : public LightData { * The light module manages light data buffers and light culling system. */ class LightModule { - // friend ShadowModule; + friend ShadowModule; private: /* Keep tile count reasonable for memory usage and 2D culling performance. */ @@ -125,7 +152,7 @@ class LightModule { public: LightModule(Instance &inst) : inst_(inst){}; - ~LightModule(){}; + ~LightModule(); void begin_sync(); void sync_light(const Object *ob, ObjectHandle &handle); @@ -138,21 +165,8 @@ class LightModule { void debug_draw(View &view, GPUFrameBuffer *view_fb); - void bind_resources(DRWShadingGroup *grp) - { - DRW_shgroup_storage_block_ref(grp, "light_buf", &culling_light_buf_); - DRW_shgroup_storage_block_ref(grp, "light_cull_buf", &culling_data_buf_); - DRW_shgroup_storage_block_ref(grp, "light_zbin_buf", &culling_zbin_buf_); - DRW_shgroup_storage_block_ref(grp, "light_tile_buf", &culling_tile_buf_); -#if 0 - DRW_shgroup_uniform_texture(grp, "shadow_atlas_tx", inst_.shadows.atlas_tx_get()); - DRW_shgroup_uniform_texture(grp, "shadow_tilemaps_tx", inst_.shadows.tilemap_tx_get()); -#endif - } - template void bind_resources(draw::detail::PassBase *pass) { - /* Storage Buf. */ pass->bind_ssbo(LIGHT_CULL_BUF_SLOT, &culling_data_buf_); pass->bind_ssbo(LIGHT_BUF_SLOT, &culling_light_buf_); pass->bind_ssbo(LIGHT_ZBIN_BUF_SLOT, &culling_zbin_buf_); diff --git a/source/blender/draw/engines/eevee_next/eevee_material.cc b/source/blender/draw/engines/eevee_next/eevee_material.cc index d190a1f17a3..43c91dc32d5 100644 --- a/source/blender/draw/engines/eevee_next/eevee_material.cc +++ b/source/blender/draw/engines/eevee_next/eevee_material.cc @@ -300,7 +300,9 @@ MaterialArray &MaterialModule::material_array_get(Object *ob, bool has_motion) for (auto i : IndexRange(materials_len)) { ::Material *blender_mat = material_from_slot(ob, i); Material &mat = material_sync(ob, blender_mat, to_material_geometry(ob), has_motion); - material_array_.materials.append(&mat); + /* \note: Perform a whole copy since next material_sync() can move the Material memory location + * (i.e: because of its container growing) */ + material_array_.materials.append(mat); material_array_.gpu_materials.append(mat.shading.gpumat); } return material_array_; diff --git a/source/blender/draw/engines/eevee_next/eevee_material.hh b/source/blender/draw/engines/eevee_next/eevee_material.hh index f4b1f60b456..c85ff5f8665 100644 --- a/source/blender/draw/engines/eevee_next/eevee_material.hh +++ b/source/blender/draw/engines/eevee_next/eevee_material.hh @@ -213,7 +213,7 @@ struct Material { }; struct MaterialArray { - Vector materials; + Vector materials; Vector gpu_materials; }; diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc index b1ab2f3ffc9..94ce44522ba 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc @@ -46,6 +46,8 @@ void WorldPipeline::sync(GPUMaterial *gpumat) world_ps_.bind_image("rp_emission_img", &rbufs.emission_tx); world_ps_.bind_image("rp_cryptomatte_img", &rbufs.cryptomatte_tx); + world_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); + world_ps_.draw(DRW_cache_fullscreen_quad_get(), handle); /* To allow opaque pass rendering over it. */ world_ps_.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS); @@ -58,6 +60,39 @@ void WorldPipeline::render(View &view) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Shadow Pipeline + * + * \{ */ + +void ShadowPipeline::sync() +{ + surface_ps_.init(); + /* TODO(fclem): Add state for rendering to empty framebuffer without depth test. + * For now this is only here for avoiding the rasterizer discard state. */ + surface_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + surface_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); + surface_ps_.bind_texture(SHADOW_RENDER_MAP_SLOT, &inst_.shadows.render_map_tx_); + surface_ps_.bind_image(SHADOW_ATLAS_SLOT, &inst_.shadows.atlas_tx_); + surface_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); + surface_ps_.bind_ssbo(SHADOW_PAGE_INFO_SLOT, &inst_.shadows.pages_infos_data_); + inst_.sampling.bind_resources(&surface_ps_); + + surface_ps_.framebuffer_set(&inst_.shadows.render_fb_); +} + +PassMain::Sub *ShadowPipeline::surface_material_add(GPUMaterial *gpumat) +{ + return &surface_ps_.sub(GPU_material_get_name(gpumat)); +} + +void ShadowPipeline::render(View &view) +{ + inst_.manager->submit(surface_ps_, view); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Forward Pass * @@ -123,6 +158,7 @@ void ForwardPipeline::sync() opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); inst_.lights.bind_resources(&opaque_ps_); + inst_.shadows.bind_resources(&opaque_ps_); inst_.sampling.bind_resources(&opaque_ps_); inst_.cryptomatte.bind_resources(&opaque_ps_); } @@ -145,9 +181,10 @@ void ForwardPipeline::sync() /* Textures. */ sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); /* Uniform Buf. */ - opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); + sub.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); inst_.lights.bind_resources(&sub); + inst_.shadows.bind_resources(&sub); inst_.sampling.bind_resources(&sub); } } @@ -225,7 +262,7 @@ void ForwardPipeline::render(View &view, // inst_.hiz_buffer.update(); // } - // inst_.shadows.set_view(view, depth_tx); + inst_.shadows.set_view(view); GPU_framebuffer_bind(combined_fb); inst_.manager->submit(opaque_ps_, view); diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.hh b/source/blender/draw/engines/eevee_next/eevee_pipeline.hh index fac82151ab2..a437ca8c522 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.hh +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.hh @@ -43,6 +43,28 @@ class WorldPipeline { /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Shadow Pass + * + * \{ */ + +class ShadowPipeline { + private: + Instance &inst_; + + PassMain surface_ps_ = {"Shadow.Surface"}; + + public: + ShadowPipeline(Instance &inst) : inst_(inst){}; + + PassMain::Sub *surface_material_add(GPUMaterial *gpumat); + + void sync(); + void render(View &view); +}; + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Forward Pass * @@ -177,19 +199,19 @@ class PipelineModule { WorldPipeline world; // DeferredPipeline deferred; ForwardPipeline forward; - // ShadowPipeline shadow; + ShadowPipeline shadow; // VelocityPipeline velocity; UtilityTexture utility_tx; public: - PipelineModule(Instance &inst) : world(inst), forward(inst){}; + PipelineModule(Instance &inst) : world(inst), forward(inst), shadow(inst){}; void sync() { // deferred.sync(); forward.sync(); - // shadow.sync(); + shadow.sync(); // velocity.sync(); } @@ -227,8 +249,7 @@ class PipelineModule { /* TODO(fclem) volume pass. */ return nullptr; case MAT_PIPE_SHADOW: - // return shadow.material_add(blender_mat, gpumat); - break; + return shadow.surface_material_add(gpumat); } return nullptr; } diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc index 64b1d4891a9..f27ced53e39 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc @@ -142,6 +142,30 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_ return "eevee_light_culling_tile"; case LIGHT_CULLING_ZBIN: return "eevee_light_culling_zbin"; + case SHADOW_DEBUG: + return "eevee_shadow_debug"; + case SHADOW_PAGE_ALLOCATE: + return "eevee_shadow_page_allocate"; + case SHADOW_PAGE_CLEAR: + return "eevee_shadow_page_clear"; + case SHADOW_PAGE_DEFRAG: + return "eevee_shadow_page_defrag"; + case SHADOW_PAGE_FREE: + return "eevee_shadow_page_free"; + case SHADOW_PAGE_MASK: + return "eevee_shadow_page_mask"; + case SHADOW_TILEMAP_BOUNDS: + return "eevee_shadow_tilemap_bounds"; + case SHADOW_TILEMAP_FINALIZE: + return "eevee_shadow_tilemap_finalize"; + case SHADOW_TILEMAP_INIT: + return "eevee_shadow_tilemap_init"; + case SHADOW_TILEMAP_TAG_UPDATE: + return "eevee_shadow_tag_update"; + case SHADOW_TILEMAP_TAG_USAGE_OPAQUE: + return "eevee_shadow_tag_usage_opaque"; + case SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT: + return "eevee_shadow_tag_usage_transparent"; /* To avoid compiler warning about missing case. */ case MAX_SHADER_TYPE: return ""; @@ -198,8 +222,17 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu /* WORKAROUND: Avoid utility texture merge error. TODO: find a cleaner fix. */ for (auto &resource : info.batch_resources_) { if (resource.bind_type == ShaderCreateInfo::Resource::BindType::SAMPLER) { - if (resource.slot == RBUFS_UTILITY_TEX_SLOT) { - resource.slot = GPU_max_textures_frag() - 1; + switch (resource.slot) { + case RBUFS_UTILITY_TEX_SLOT: + resource.slot = GPU_max_textures_frag() - 1; + break; + // case SHADOW_RENDER_MAP_SLOT: /* Does not compile because it is a define. */ + case SHADOW_ATLAS_TEX_SLOT: + resource.slot = GPU_max_textures_frag() - 2; + break; + case SHADOW_TILEMAPS_TEX_SLOT: + resource.slot = GPU_max_textures_frag() - 3; + break; } } } @@ -214,9 +247,10 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT) == false && pipeline_type == MAT_PIPE_FORWARD) { - /* Opaque forward do support AOVs and render pass. */ + /* Opaque forward do support AOVs and render pass if not using transparency. */ info.additional_info("eevee_aov_out"); info.additional_info("eevee_render_pass_out"); + info.additional_info("eevee_cryptomatte_out"); } if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC)) { @@ -389,9 +423,11 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu break; case MAT_PIPE_FORWARD_PREPASS: case MAT_PIPE_DEFERRED_PREPASS: - case MAT_PIPE_SHADOW: info.additional_info("eevee_surf_depth"); break; + case MAT_PIPE_SHADOW: + info.additional_info("eevee_surf_shadow"); + break; case MAT_PIPE_DEFERRED: info.additional_info("eevee_surf_deferred"); break; diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.hh b/source/blender/draw/engines/eevee_next/eevee_shader.hh index 88538557c07..df689bb2717 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader.hh @@ -62,6 +62,19 @@ enum eShaderType { MOTION_BLUR_TILE_FLATTEN_RENDER, MOTION_BLUR_TILE_FLATTEN_VIEWPORT, + SHADOW_DEBUG, + SHADOW_PAGE_ALLOCATE, + SHADOW_PAGE_CLEAR, + SHADOW_PAGE_DEFRAG, + SHADOW_PAGE_FREE, + SHADOW_PAGE_MASK, + SHADOW_TILEMAP_BOUNDS, + SHADOW_TILEMAP_FINALIZE, + SHADOW_TILEMAP_INIT, + SHADOW_TILEMAP_TAG_UPDATE, + SHADOW_TILEMAP_TAG_USAGE_OPAQUE, + SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT, + MAX_SHADER_TYPE, }; diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh index cd98564f8e0..fb8b355c38f 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh @@ -21,6 +21,9 @@ namespace blender::eevee { +class ShadowDirectional; +class ShadowPunctual; + using namespace draw; constexpr eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT; @@ -46,36 +49,21 @@ enum eDebugMode : uint32_t { */ DEBUG_HIZ_VALIDATION = 2u, /** - * Tile-maps to screen. Is also present in other modes. - * - Black pixels, no pages allocated. - * - Green pixels, pages cached. - * - Red pixels, pages allocated. + * Show tiles depending on their status. */ DEBUG_SHADOW_TILEMAPS = 10u, /** - * Random color per pages. Validates page density allocation and sampling. + * Show content of shadow map. Used to verify projection code. */ - DEBUG_SHADOW_PAGES = 11u, + DEBUG_SHADOW_VALUES = 11u, /** - * Outputs random color per tile-map (or tile-map level). Validates tile-maps coverage. - * Black means not covered by any tile-maps LOD of the shadow. + * Show random color for each tile. Verify allocation and LOD assignment. */ - DEBUG_SHADOW_LOD = 12u, + DEBUG_SHADOW_TILE_RANDOM_COLOR = 12u, /** - * Outputs white pixels for pages allocated and black pixels for unused pages. - * This needs DEBUG_SHADOW_PAGE_ALLOCATION_ENABLED defined in order to work. + * Show random color for each tile. Verify distribution and LOD transitions. */ - DEBUG_SHADOW_PAGE_ALLOCATION = 13u, - /** - * Outputs the tile-map atlas. Default tile-map is too big for the usual screen resolution. - * Try lowering SHADOW_TILEMAP_PER_ROW and SHADOW_MAX_TILEMAP before using this option. - */ - DEBUG_SHADOW_TILE_ALLOCATION = 14u, - /** - * Visualize linear depth stored in the atlas regions of the active light. - * This way, one can check if the rendering, the copying and the shadow sampling functions works. - */ - DEBUG_SHADOW_SHADOW_DEPTH = 15u + DEBUG_SHADOW_TILEMAP_RANDOM_COLOR = 13u, }; /** \} */ @@ -176,6 +164,11 @@ struct CameraData { float clip_near; float clip_far; eCameraType type; + /** World space distance between view corners at unit distance from camera. */ + float screen_diagonal_length; + float _pad0; + float _pad1; + float _pad2; bool1 initialized; @@ -501,8 +494,7 @@ static inline float regular_polygon_side_length(float sides_count) * Start first corners at theta == 0. */ static inline float circle_to_polygon_radius(float sides_count, float theta) { - /* From Graphics Gems from CryENGINE 3 (Siggraph 2013) by Tiago Sousa (slide - * 36). */ + /* From Graphics Gems from CryENGINE 3 (Siggraph 2013) by Tiago Sousa (slide 36). */ float side_angle = (2.0f * M_PI) / sides_count; return cosf(side_angle * 0.5f) / cosf(theta - side_angle * floorf((sides_count * theta + M_PI) / (2.0f * M_PI))); @@ -582,10 +574,11 @@ BLI_STATIC_ASSERT_ALIGN(LightCullingData, 16) enum eLightType : uint32_t { LIGHT_SUN = 0u, - LIGHT_POINT = 1u, - LIGHT_SPOT = 2u, - LIGHT_RECT = 3u, - LIGHT_ELLIPSE = 4u + LIGHT_SUN_ORTHO = 1u, + LIGHT_POINT = 10u, + LIGHT_SPOT = 11u, + LIGHT_RECT = 20u, + LIGHT_ELLIPSE = 21u }; static inline bool is_area_light(eLightType type) @@ -593,6 +586,11 @@ static inline bool is_area_light(eLightType type) return type >= LIGHT_RECT; } +static inline bool is_sun_light(eLightType type) +{ + return type < LIGHT_POINT; +} + struct LightData { /** Normalized object matrix. Last column contains data accessible using the following macros. */ float4x4 object_mat; @@ -602,6 +600,9 @@ struct LightData { #define _radius _area_size_x #define _spot_mul object_mat[2][3] #define _spot_bias object_mat[3][3] + /** Scale to convert from world units to tile space of the clipmap_lod_max. */ +#define _clipmap_origin_x object_mat[2][3] +#define _clipmap_origin_y object_mat[3][3] /** Aliases for axes. */ #ifndef USE_GPU_SHADER_CREATE_INFO # define _right object_mat[0].xyz() @@ -614,34 +615,210 @@ struct LightData { # define _back object_mat[2].xyz # define _position object_mat[3].xyz #endif - /** Influence radius (inverted and squared) adjusted for Surface / Volume power. */ + /** Punctual : Influence radius (inverted and squared) adjusted for Surface / Volume power. */ float influence_radius_invsqr_surface; float influence_radius_invsqr_volume; - /** Maximum influence radius. Used for culling. */ + /** Punctual : Maximum influence radius. Used for culling. Equal to clip far distance. */ float influence_radius_max; - /** Index of the shadow struct on CPU. -1 means no shadow. */ - int shadow_id; + /** Special radius factor for point lighting. */ + float radius_squared; /** NOTE: It is ok to use float3 here. A float is declared right after it. * float3 is also aligned to 16 bytes. */ float3 color; + /** Light Type. */ + eLightType type; + /** Spot size. Aligned to size of float2. */ + float2 spot_size_inv; + /** Spot angle tangent. */ + float spot_tan; + /** Reuse for directional LOD bias. */ +#define _clipmap_lod_bias spot_tan /** Power depending on shader type. */ float diffuse_power; float specular_power; float volume_power; float transmit_power; - /** Special radius factor for point lighting. */ - float radius_squared; - /** Light Type. */ - eLightType type; - /** Spot angle tangent. */ - float spot_tan; - /** Spot size. Aligned to size of float2. */ - float2 spot_size_inv; - /** Associated shadow data. Only valid if shadow_id is not LIGHT_NO_SHADOW. */ - // ShadowData shadow_data; + + /** --- Shadow Data --- */ + /** Directional : Near clip distance. Float stored as int for atomic operations. */ + int clip_near; + int clip_far; + /** Directional : Clip-map LOD range to avoid sampling outside of valid range. */ + int clipmap_lod_min; + int clipmap_lod_max; + /** Index of the first tile-map. */ + int tilemap_index; + /** Directional : Offset of the LOD min in LOD min tile units. */ + int2 clipmap_base_offset; + /** Punctual & Directional : Normal matrix packed for automatic bias. */ + float2 normal_mat_packed; }; BLI_STATIC_ASSERT_ALIGN(LightData, 16) +static inline int light_tilemap_max_get(LightData light) +{ + /* This is not something we need in performance critical code. */ + return light.tilemap_index + (light.clipmap_lod_max - light.clipmap_lod_min); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shadows + * + * Shadow data for either a directional shadow or a punctual shadow. + * + * A punctual shadow is composed of 1, 5 or 6 shadow regions. + * Regions are sorted in this order -Z, +X, -X, +Y, -Y, +Z. + * Face index is computed from light's object space coordinates. + * + * A directional light shadow is composed of multiple clip-maps with each level + * covering twice as much area as the previous one. + * \{ */ + +enum eShadowProjectionType : uint32_t { + SHADOW_PROJECTION_CUBEFACE = 0u, + SHADOW_PROJECTION_CLIPMAP = 1u, + SHADOW_PROJECTION_CASCADE = 2u, +}; + +static inline int2 shadow_cascade_grid_offset(int2 base_offset, int level_relative) +{ + return (base_offset * level_relative) / (1 << 16); +} + +/** + * Small descriptor used for the tile update phase. Updated by CPU & uploaded to GPU each redraw. + */ +struct ShadowTileMapData { + /** Cached, used for rendering. */ + float4x4 viewmat, winmat; + /** Punctual : Corners of the frustum. (vec3 padded to vec4) */ + float4 corners[4]; + /** Integer offset of the center of the 16x16 tiles from the origin of the tile space. */ + int2 grid_offset; + /** Shift between previous and current grid_offset. Allows update tagging. */ + int2 grid_shift; + /** True for punctual lights. */ + eShadowProjectionType projection_type; + /** Multiple of SHADOW_TILEDATA_PER_TILEMAP. Offset inside the tile buffer. */ + int tiles_index; + /** Index of persistent data in the persistent data buffer. */ + int clip_data_index; + /** Bias LOD to tag for usage to lower the amount of tile used. */ + float lod_bias; +}; +BLI_STATIC_ASSERT_ALIGN(ShadowTileMapData, 16) + +/** + * Per tilemap data persistent on GPU. + */ +struct ShadowTileMapClip { + /** Clip distances that were used to render the pages. */ + float clip_near_stored; + float clip_far_stored; + /** Near and far clip distances for directional. Float stored as int for atomic operations. */ + int clip_near; + int clip_far; +}; +BLI_STATIC_ASSERT_ALIGN(ShadowTileMapClip, 16) + +struct ShadowPagesInfoData { + /** Number of free pages in the free page buffer. */ + int page_free_count; + /** Number of page allocations needed for this cycle. */ + int page_alloc_count; + /** Index of the next cache page in the cached page buffer. */ + uint page_cached_next; + /** Index of the first page in the buffer since the last defrag. */ + uint page_cached_start; + /** Index of the last page in the buffer since the last defrag. */ + uint page_cached_end; + /** Number of views to be rendered during the shadow update pass. */ + int view_count; + /** Physical page size in pixel. Pages are all squares. */ + int page_size; + + int _pad0; +}; +BLI_STATIC_ASSERT_ALIGN(ShadowPagesInfoData, 16) + +struct ShadowStatistics { + /** Statistics that are read back to CPU after a few frame (to avoid stall). */ + int page_used_count; + int page_update_count; + int page_allocated_count; + int page_rendered_count; +}; +BLI_STATIC_ASSERT_ALIGN(ShadowStatistics, 16) + +/** Decoded tile data structure. */ +struct ShadowTileData { + /** Page inside the virtual shadow map atlas. */ + uint2 page; + /** Page index inside pages_cached_buf. Only valid if `is_cached` is true. */ + uint cache_index; + /** LOD pointed to LOD 0 tile page. (cube-map only). */ + uint lod; + /** If the tile is needed for rendering. */ + bool is_used; + /** True if an update is needed. This persists even if the tile gets unused. */ + bool do_update; + /** True if the tile owns the page (mutually exclusive with `is_cached`). */ + bool is_allocated; + /** True if the tile has been staged for rendering. This will remove the `do_update` flag. */ + bool is_rendered; + /** True if the tile is inside the pages_cached_buf (mutually exclusive with `is_allocated`). */ + bool is_cached; +}; +/** \note Stored packed as a uint. */ +#define ShadowTileDataPacked uint + +enum eShadowFlag : uint32_t { + SHADOW_NO_DATA = 0u, + SHADOW_IS_CACHED = (1u << 27u), + SHADOW_IS_ALLOCATED = (1u << 28u), + SHADOW_DO_UPDATE = (1u << 29u), + SHADOW_IS_RENDERED = (1u << 30u), + SHADOW_IS_USED = (1u << 31u) +}; + +static inline ShadowTileData shadow_tile_unpack(ShadowTileDataPacked data) +{ + ShadowTileData tile; + /* Tweaked for SHADOW_PAGE_PER_ROW = 64. */ + tile.page.x = data & 63u; + tile.page.y = (data >> 6u) & 63u; + /* -- 12 bits -- */ + /* Tweaked for SHADOW_TILEMAP_LOD < 8. */ + tile.lod = (data >> 12u) & 7u; + /* -- 15 bits -- */ + /* Tweaked for SHADOW_MAX_TILEMAP = 4096. */ + tile.cache_index = (data >> 15u) & 4095u; + /* -- 27 bits -- */ + tile.is_used = (data & SHADOW_IS_USED) != 0; + tile.is_cached = (data & SHADOW_IS_CACHED) != 0; + tile.is_allocated = (data & SHADOW_IS_ALLOCATED) != 0; + tile.is_rendered = (data & SHADOW_IS_RENDERED) != 0; + tile.do_update = (data & SHADOW_DO_UPDATE) != 0; + return tile; +} + +static inline ShadowTileDataPacked shadow_tile_pack(ShadowTileData tile) +{ + uint data; + data = (tile.page.x & 63u); + data |= (tile.page.y & 63u) << 6u; + data |= (tile.lod & 7u) << 12u; + data |= (tile.cache_index & 4095u) << 15u; + data |= (tile.is_used ? uint(SHADOW_IS_USED) : 0); + data |= (tile.is_allocated ? uint(SHADOW_IS_ALLOCATED) : 0); + data |= (tile.is_cached ? uint(SHADOW_IS_CACHED) : 0); + data |= (tile.is_rendered ? uint(SHADOW_IS_RENDERED) : 0); + data |= (tile.do_update ? uint(SHADOW_DO_UPDATE) : 0); + return data; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -761,6 +938,13 @@ using LightDataBuf = draw::StorageArrayBuffer; using MotionBlurDataBuf = draw::UniformBuffer; using MotionBlurTileIndirectionBuf = draw::StorageBuffer; using SamplingDataBuf = draw::StorageBuffer; +using ShadowStatisticsBuf = draw::StorageBuffer; +using ShadowPagesInfoDataBuf = draw::StorageBuffer; +using ShadowPageHeapBuf = draw::StorageVectorBuffer; +using ShadowPageCacheBuf = draw::StorageArrayBuffer; +using ShadowTileMapDataBuf = draw::StorageVectorBuffer; +using ShadowTileMapClipBuf = draw::StorageArrayBuffer; +using ShadowTileDataBuf = draw::StorageArrayBuffer; using VelocityGeometryBuf = draw::StorageArrayBuffer; using VelocityIndexBuf = draw::StorageArrayBuffer; using VelocityObjectBuf = draw::StorageArrayBuffer; diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.cc b/source/blender/draw/engines/eevee_next/eevee_shadow.cc new file mode 100644 index 00000000000..c7d6dcb62d7 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.cc @@ -0,0 +1,1180 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. + */ + +/** \file + * \ingroup eevee + * + * The shadow module manages shadow update tagging & shadow rendering. + */ + +#include "BKE_global.h" +#include "BLI_rect.h" + +#include "eevee_instance.hh" + +#include "draw_debug.hh" + +namespace blender::eevee { + +/* -------------------------------------------------------------------- */ +/** \name Tile map + * + * \{ */ + +void ShadowTileMap::sync_orthographic(const float4x4 &object_mat_, + int2 origin_offset, + int clipmap_level, + float lod_bias_, + eShadowProjectionType projection_type_) +{ + if (projection_type != projection_type_ || (level != clipmap_level)) { + set_dirty(); + } + projection_type = projection_type_; + level = clipmap_level; + + if (grid_shift == int2(0)) { + /* Only replace shift if it is not already dirty. */ + grid_shift = origin_offset - grid_offset; + } + grid_offset = origin_offset; + + if (!equals_m4m4(object_mat.ptr(), object_mat_.ptr())) { + object_mat = object_mat_; + set_dirty(); + } + + lod_bias = lod_bias_; + + float tile_size = ShadowDirectional::tile_size_get(level); + + /* object_mat is a rotation matrix. Reduce imprecision by taking the transpose which is also the + * inverse in this particular case. */ + viewmat = math::transpose(object_mat); + + float half_size = ShadowDirectional::coverage_get(level) / 2.0f; + float2 win_offset = float2(grid_offset) * tile_size; + orthographic_m4(winmat.ptr(), + -half_size + win_offset.x, + half_size + win_offset.x, + -half_size + win_offset.y, + half_size + win_offset.y, + /* Near/far is computed on GPU using casters bounds. */ + -1.0, + 1.0); +} + +void ShadowTileMap::sync_cubeface( + const float4x4 &object_mat_, float near_, float far_, eCubeFace face, float lod_bias_) +{ + if (projection_type != SHADOW_PROJECTION_CUBEFACE || (cubeface != face) || (near != near_) || + (far != far_)) { + set_dirty(); + } + projection_type = SHADOW_PROJECTION_CUBEFACE; + cubeface = face; + near = near_; + far = far_; + lod_bias = lod_bias_; + grid_offset = int2(0); + + if (!equals_m4m4(object_mat.ptr(), object_mat_.ptr())) { + object_mat = object_mat_; + set_dirty(); + } + + perspective_m4(winmat.ptr(), -near, near, -near, near, near, far); + viewmat = float4x4(shadow_face_mat[cubeface]) * math::invert(object_mat); + + /* Update corners. */ + float4x4 viewinv = object_mat; + corners[0] = float4(viewinv.location(), 0.0f); + corners[1] = float4(math::transform_point(viewinv, float3(-far, -far, -far)), 0.0f); + corners[2] = float4(math::transform_point(viewinv, float3(far, -far, -far)), 0.0f); + corners[3] = float4(math::transform_point(viewinv, float3(-far, far, -far)), 0.0f); + /* Store deltas. */ + corners[2] = (corners[2] - corners[1]) / float(SHADOW_TILEMAP_RES); + corners[3] = (corners[3] - corners[1]) / float(SHADOW_TILEMAP_RES); +} + +void ShadowTileMap::debug_draw() const +{ + /** Used for debug drawing. */ + float4 debug_color[6] = {{1.0f, 0.1f, 0.1f, 1.0f}, + {0.1f, 1.0f, 0.1f, 1.0f}, + {0.0f, 0.2f, 1.0f, 1.0f}, + {1.0f, 1.0f, 0.3f, 1.0f}, + {0.1f, 0.1f, 0.1f, 1.0f}, + {1.0f, 1.0f, 1.0f, 1.0f}}; + float4 color = + debug_color[((projection_type == SHADOW_PROJECTION_CUBEFACE ? cubeface : level) + 9999) % 6]; + + float4x4 persinv = winmat * viewmat; + drw_debug_matrix_as_bbox(math::invert(persinv), color); + + // int64_t div = ShadowTileMapPool::maps_per_row; + // std::stringstream ss; + // ss << "[" << tiles_index % div << ":" << tiles_index / div << "]"; + // std::string text = ss.str(); + + // float3 pos = persinv * float3(0.0f, 0.0f, (projection_type) ? 1.0f : 0.0f); + + // uchar ucolor[4]; + // rgba_float_to_uchar(ucolor, color); + // struct DRWTextStore *dt = DRW_text_cache_ensure(); + // DRW_text_cache_add(dt, pos, text.c_str(), text.size(), 0, 0, DRW_TEXT_CACHE_GLOBALSPACE, + // ucolor); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Tile map pool + * + * \{ */ + +ShadowTileMapPool::ShadowTileMapPool() +{ + free_indices.reserve(SHADOW_MAX_TILEMAP); + /* Reverse order to help debugging (first allocated tile-map will get 0). */ + for (int i = SHADOW_MAX_TILEMAP - 1; i >= 0; i--) { + free_indices.append(i * SHADOW_TILEDATA_PER_TILEMAP); + } + + int2 extent; + extent.x = min_ii(SHADOW_MAX_TILEMAP, maps_per_row) * ShadowTileMap::tile_map_resolution; + extent.y = (SHADOW_MAX_TILEMAP / maps_per_row) * ShadowTileMap::tile_map_resolution; + + eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_SHADER_WRITE; + tilemap_tx.ensure_2d(GPU_R32UI, extent, usage); + tilemap_tx.clear(uint4(0)); +} + +ShadowTileMap *ShadowTileMapPool::acquire() +{ + if (free_indices.is_empty()) { + /* Grow the tile-map buffer. See `end_sync`. */ + for (auto i : IndexRange(free_indices.size(), SHADOW_MAX_TILEMAP)) { + free_indices.append(i * SHADOW_TILEDATA_PER_TILEMAP); + } + } + int index = free_indices.pop_last(); + return &tilemap_pool.construct(ShadowTileMap(index)); +} + +void ShadowTileMapPool::release(Span free_list) +{ + for (ShadowTileMap *map : free_list) { + free_indices.append(map->tiles_index); + tilemap_pool.destruct(*map); + } +} + +void ShadowTileMapPool::end_sync(ShadowModule &module) +{ + tilemaps_data.push_update(); + + uint needed_tilemap_capacity = (free_indices.size() + tilemap_pool.size()); + if (needed_tilemap_capacity != (tiles_data.size() / SHADOW_TILEDATA_PER_TILEMAP)) { + tiles_data.resize(needed_tilemap_capacity * SHADOW_TILEDATA_PER_TILEMAP); + tilemaps_clip.resize(needed_tilemap_capacity); + /* We reallocated the tile-map buffer, discarding all the data it contained. + * We need to re-initialize the page heaps. */ + module.do_full_update = true; + } + + tilemaps_unused.clear(); + int64_t newly_unused_count = free_indices.size() - last_free_len; + if (newly_unused_count > 0) { + /* Upload tile-map indices which pages needs to be pushed back to the free page heap. */ + Span newly_unused_indices = free_indices.as_span().slice(last_free_len, + newly_unused_count); + for (uint index : newly_unused_indices) { + /* Push a dummy tile-map to a unused tile-map buffer. It is then processed through the some + * of the setup steps to release the pages. */ + ShadowTileMapData tilemap_data = {}; + tilemap_data.tiles_index = index; + tilemap_data.clip_data_index = 0; + tilemap_data.grid_shift = int2(SHADOW_TILEMAP_RES); + tilemap_data.projection_type = SHADOW_PROJECTION_CUBEFACE; + + tilemaps_unused.append(tilemap_data); + } + tilemaps_unused.push_update(); + } + + last_free_len = free_indices.size(); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shadow Punctual + * + * \{ */ + +void ShadowPunctual::sync(eLightType light_type, + const float4x4 &object_mat, + float cone_aperture, + float near_clip, + float far_clip) +{ + if (light_type == LIGHT_SPOT) { + tilemaps_needed_ = (cone_aperture > DEG2RADF(90.0f)) ? 5 : 1; + } + else if (is_area_light(light_type)) { + tilemaps_needed_ = 5; + } + else { + tilemaps_needed_ = 6; + } + + far_ = max_ff(far_clip, 3e-4f); + near_ = min_ff(near_clip, far_clip - 1e-4f); + light_type_ = light_type; + + /* Keep custom data. */ + size_x_ = _area_size_x; + size_y_ = _area_size_y; + + position_ = float3(object_mat[3]); +} + +void ShadowPunctual::release_excess_tilemaps() +{ + if (tilemaps_.size() <= tilemaps_needed_) { + return; + } + auto span = tilemaps_.as_span(); + shadows_.tilemap_pool.release(span.drop_front(tilemaps_needed_)); + tilemaps_ = span.take_front(tilemaps_needed_); +} + +void ShadowPunctual::end_sync(Light &light, float lod_bias) +{ + ShadowTileMapPool &tilemap_pool = shadows_.tilemap_pool; + + float4x4 obmat_tmp = light.object_mat; + + /* Clear embedded custom data. */ + obmat_tmp[0][3] = obmat_tmp[1][3] = obmat_tmp[2][3] = 0.0f; + obmat_tmp[3][3] = 1.0f; + + /* Acquire missing tile-maps. */ + while (tilemaps_.size() < tilemaps_needed_) { + tilemaps_.append(tilemap_pool.acquire()); + } + + tilemaps_[Z_NEG]->sync_cubeface(obmat_tmp, near_, far_, Z_NEG, lod_bias); + if (tilemaps_needed_ >= 5) { + tilemaps_[X_POS]->sync_cubeface(obmat_tmp, near_, far_, X_POS, lod_bias); + tilemaps_[X_NEG]->sync_cubeface(obmat_tmp, near_, far_, X_NEG, lod_bias); + tilemaps_[Y_POS]->sync_cubeface(obmat_tmp, near_, far_, Y_POS, lod_bias); + tilemaps_[Y_NEG]->sync_cubeface(obmat_tmp, near_, far_, Y_NEG, lod_bias); + } + if (tilemaps_needed_ == 6) { + tilemaps_[Z_POS]->sync_cubeface(obmat_tmp, near_, far_, Z_POS, lod_bias); + } + + /* Normal matrix to convert geometric normal to optimal bias. */ + float4x4 &winmat = tilemaps_[Z_NEG]->winmat; + float4x4 normal_mat = math::invert(math::transpose(winmat)); + light.normal_mat_packed.x = normal_mat[3][2]; + light.normal_mat_packed.y = normal_mat[3][3]; + + light.tilemap_index = tilemap_pool.tilemaps_data.size(); + + /* A bit weird give we are inside a punctual shadow, but this is + * in order to make light_tilemap_max_get() work. */ + light.clipmap_lod_min = 0; + light.clipmap_lod_max = tilemaps_needed_ - 1; + + union { + float f; + int32_t i; + } as_int; + as_int.f = near_; + light.clip_near = as_int.i; + as_int.f = far_; + light.clip_far = as_int.i; + + for (ShadowTileMap *tilemap : tilemaps_) { + /* Add shadow tile-maps grouped by lights to the GPU buffer. */ + tilemap_pool.tilemaps_data.append(*tilemap); + tilemap->set_updated(); + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Directional Shadow Maps + * + * In order to improve shadow map density, we switch between two tile-map distribution mode. + * One is beater suited for large FOV (clip-map), the other for really small FOV or Orthographic + * projections (cascade). + * + * Clip-map distribution centers a number of log2 sized tile-maps around the view position. + * https://developer.nvidia.com/gpugems/gpugems2/part-i-geometric-complexity/chapter-2-terrain-rendering-using-gpu-based-geometry + * + * Cascade distribution puts tile-maps along the frustum projection to the light space. + * https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-parallel-split-shadow-maps-programmable-gpus + * + * We choose to distribute cascades linearly to achieve uniform density and simplify lookup. + * Using clip-map instead of cascades for perspective view also allows for better caching. + * \{ */ + +eShadowProjectionType ShadowDirectional::directional_distribution_type_get(const Camera &camera) +{ + /* TODO(fclem): Enable the cascade projection if the FOV is tiny in perspective mode. */ + return camera.is_perspective() ? SHADOW_PROJECTION_CLIPMAP : SHADOW_PROJECTION_CASCADE; +} + +/************************************************************************ + * Cascade Distribution * + ************************************************************************/ + +void ShadowDirectional::cascade_tilemaps_distribution_near_far_points(const Camera &camera, + float3 &near_point, + float3 &far_point) +{ + const CameraData &cam_data = camera.data_get(); + /* Ideally we should only take the intersection with the scene bounds. */ + far_point = (camera.position() - camera.forward() * cam_data.clip_far) * + float3x3(object_mat_.view<3, 3>()); + near_point = (camera.position() - camera.forward() * cam_data.clip_near) * + float3x3(object_mat_.view<3, 3>()); +} + +/* \note All tile-maps are meant to have the same LOD but we still return a range starting at the + * unique LOD. */ +IndexRange ShadowDirectional::cascade_level_range(const Camera &camera, float lod_bias) +{ + using namespace blender::math; + + /* 16 is arbitrary. To avoid too much tile-map per directional lights. */ + const int max_tilemap_per_shadows = 16; + const CameraData &cam_data = camera.data_get(); + + float3 near_point, far_point; + cascade_tilemaps_distribution_near_far_points(camera, near_point, far_point); + + /* This gives the maximum resolution in depth we can have with a fixed set of tile-maps. Gives + * the best results when view direction is orthogonal to the light direction. */ + float depth_range_in_shadow_space = distance(far_point.xy(), near_point.xy()); + float min_depth_tilemap_size = 2 * (depth_range_in_shadow_space / max_tilemap_per_shadows); + /* This allow coverage of the whole view with a single tile-map if camera forward is colinear + * with the light direction. */ + float min_diagonal_tilemap_size = cam_data.screen_diagonal_length; + + if (camera.is_perspective()) { + /* Use the far plane diagonal if using perspective. */ + min_diagonal_tilemap_size *= cam_data.clip_far / cam_data.clip_near; + } + + /* Allow better tile-map usage without missing pages near end of view. */ + lod_bias += 0.5f; + /* Level of detail (or size) of every tile-maps of this light. */ + int lod_level = ceil(log2(max_ff(min_depth_tilemap_size, min_diagonal_tilemap_size)) + lod_bias); + + /* Tile-maps "rotate" around the first one so their effective range is only half their size. */ + float per_tilemap_coverage = ShadowDirectional::coverage_get(lod_level) * 0.5f; + /* Number of tile-maps needed to cover the whole view. */ + /* Note: floor + 0.5 to avoid 0 when parallel. */ + int tilemap_len = ceil(0.5f + depth_range_in_shadow_space / per_tilemap_coverage); + return IndexRange(lod_level, tilemap_len); +} + +/** + * Distribute tile-maps in a linear pattern along camera forward vector instead of a clipmap + * centered on camera position. + */ +void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera &camera) +{ + using namespace blender::math; + + /* All tile-maps use the first level size. */ + float half_size = ShadowDirectional::coverage_get(levels_range.first()) / 2.0f; + float tile_size = ShadowDirectional::tile_size_get(levels_range.first()); + + float3 near_point, far_point; + cascade_tilemaps_distribution_near_far_points(camera, near_point, far_point); + + float2 local_view_direction = normalize(far_point.xy() - near_point.xy()); + float2 farthest_tilemap_center = local_view_direction * half_size * (levels_range.size() - 1); + + /* Offset for smooth level transitions. */ + light.object_mat.location() = near_point; + + /* Offset in tiles from the origin to the center of the first tile-maps. */ + int2 origin_offset = int2(round(float2(near_point) / tile_size)); + /* Offset in tiles between the first and the last tile-maps. */ + int2 offset_vector = int2(round(farthest_tilemap_center / tile_size)); + + light.clipmap_base_offset = (offset_vector * (1 << 16)) / max_ii(levels_range.size() - 1, 1); + + /* \note: cascade_level_range starts the range at the unique LOD to apply to all tile-maps. */ + int level = levels_range.first(); + for (int i : IndexRange(levels_range.size())) { + ShadowTileMap *tilemap = tilemaps_[i]; + + /* Equal spacing between cascades layers since we want uniform shadow density. */ + int2 level_offset = origin_offset + shadow_cascade_grid_offset(light.clipmap_base_offset, i); + tilemap->sync_orthographic(object_mat_, level_offset, level, 0.0f, SHADOW_PROJECTION_CASCADE); + + /* Add shadow tile-maps grouped by lights to the GPU buffer. */ + shadows_.tilemap_pool.tilemaps_data.append(*tilemap); + tilemap->set_updated(); + } + + light._clipmap_origin_x = origin_offset.x * tile_size; + light._clipmap_origin_y = origin_offset.y * tile_size; + + light.type = LIGHT_SUN_ORTHO; + + /* Not really clip-maps, but this is in order to make #light_tilemap_max_get() work and determine + * the scaling. */ + light.clipmap_lod_min = levels_range.first(); + light.clipmap_lod_max = levels_range.last(); + + /* The bias is applied in cascade_level_range(). + * Using clipmap_lod_min here simplify code in shadow_directional_level(). + * Minus 1 because of the ceil().*/ + light._clipmap_lod_bias = light.clipmap_lod_min - 1; + + /* Scaling is handled by ShadowCoordinates.lod_relative. */ + /* NOTE: Not sure why 0.25 is needed here. Some zero level scaling. */ + light.normal_mat_packed.x = 0.25f; +} + +/************************************************************************ + * Clip-map Distribution * + ************************************************************************/ + +IndexRange ShadowDirectional::clipmap_level_range(const Camera &camera) +{ + using namespace blender::math; + + /* Take 16 to be able to pack offset into a single int2. */ + const int max_tilemap_per_shadows = 16; + + int user_min_level = floorf(log2(min_resolution_)); + /* Covers the farthest points of the view. */ + int max_level = ceil( + log2(camera.bound_radius() + distance(camera.bound_center(), camera.position()))); + /* We actually need to cover a bit more because of clipmap origin snapping. */ + max_level += 1; + /* Covers the closest points of the view. */ + int min_level = floor(log2(abs(camera.data_get().clip_near))); + min_level = clamp_i(user_min_level, min_level, max_level); + + IndexRange range(min_level, max_level - min_level + 1); + /* The maximum level count is bounded by the mantissa of a 32bit float. Take top-most level to + * still cover the whole view. */ + range = range.take_back(max_tilemap_per_shadows); + + return range; +} + +void ShadowDirectional::clipmap_tilemaps_distribution(Light &light, + const Camera &camera, + float lod_bias) +{ + for (int lod : IndexRange(levels_range.size())) { + ShadowTileMap *tilemap = tilemaps_[lod]; + + int level = levels_range.first() + lod; + /* Compute full offset from world origin to the smallest clipmap tile centered around the + * camera position. The offset is computed in smallest tile unit. */ + float tile_size = ShadowDirectional::tile_size_get(level); + /* Moving to light space by multiplying by the transpose (which is the inverse). */ + float2 light_space_camera_position = camera.position() * float2x3(object_mat_.view<2, 3>()); + int2 level_offset = int2(math::round(light_space_camera_position / tile_size)); + + tilemap->sync_orthographic( + object_mat_, level_offset, level, lod_bias, SHADOW_PROJECTION_CLIPMAP); + + /* Add shadow tile-maps grouped by lights to the GPU buffer. */ + shadows_.tilemap_pool.tilemaps_data.append(*tilemap); + tilemap->set_updated(); + } + + int2 pos_offset = int2(0); + int2 neg_offset = int2(0); + for (int lod : IndexRange(levels_range.size() - 1)) { + /* Since offset can only differ by one tile from the higher level, we can compress that as a + * single integer where one bit contains offset between 2 levels. Then a single bit shift in + * the shader gives the number of tile to offset in the given tile-map space. However we need + * also the sign of the offset for each level offset. To this end, we split the negative + * offsets to a separate int. + * Recovering the offset with: (pos_offset >> lod) - (neg_offset >> lod). */ + int2 lvl_offset_next = tilemaps_[lod + 1]->grid_offset; + int2 lvl_offset = tilemaps_[lod]->grid_offset; + int2 lvl_delta = lvl_offset - (lvl_offset_next << 1); + BLI_assert(math::abs(lvl_delta.x) <= 1 && math::abs(lvl_delta.y) <= 1); + pos_offset |= math::max(lvl_delta, int2(0)) << lod; + neg_offset |= math::max(-lvl_delta, int2(0)) << lod; + } + + /* Compressing to a single value to save up storage in light data. Number of levels is limited to + * 16 by `clipmap_level_range()` for this reason. */ + light.clipmap_base_offset = pos_offset | (neg_offset << 16); + + float tile_size_max = ShadowDirectional::tile_size_get(levels_range.last()); + int2 level_offset_max = tilemaps_[levels_range.size() - 1]->grid_offset; + + light.type = LIGHT_SUN; + + /* Used for selecting the clipmap level. */ + light.object_mat.location() = camera.position() * float3x3(object_mat_.view<3, 3>()); + /* Used as origin for the clipmap_base_offset trick. */ + light._clipmap_origin_x = level_offset_max.x * tile_size_max; + light._clipmap_origin_y = level_offset_max.y * tile_size_max; + + light.clipmap_lod_min = levels_range.first(); + light.clipmap_lod_max = levels_range.last(); + + light._clipmap_lod_bias = lod_bias; + + /* Half size of the min level. */ + light.normal_mat_packed.x = ShadowDirectional::tile_size_get(levels_range.first()) / 2.0f; +} + +void ShadowDirectional::sync(const float4x4 &object_mat, float min_resolution) +{ + object_mat_ = object_mat; + /* Clear embedded custom data. */ + object_mat_[0][3] = object_mat_[1][3] = object_mat_[2][3] = 0.0f; + object_mat_[3][3] = 1.0f; + /* Remove translation. */ + object_mat_.location() = float3(0.0f); + + min_resolution_ = min_resolution; +} + +void ShadowDirectional::release_excess_tilemaps(const Camera &camera, float lod_bias) +{ + IndexRange levels_new = directional_distribution_type_get(camera) == SHADOW_PROJECTION_CASCADE ? + cascade_level_range(camera, lod_bias) : + clipmap_level_range(camera); + + if (levels_range == levels_new) { + return; + } + + IndexRange isect_range = levels_range.intersect(levels_new); + IndexRange before_range(levels_range.start(), isect_range.start() - levels_range.start()); + IndexRange after_range(isect_range.one_after_last(), + levels_range.one_after_last() - isect_range.one_after_last()); + + auto span = tilemaps_.as_span(); + shadows_.tilemap_pool.release(span.slice(before_range.shift(-levels_range.start()))); + shadows_.tilemap_pool.release(span.slice(after_range.shift(-levels_range.start()))); + tilemaps_ = span.slice(isect_range.shift(-levels_range.start())); + levels_range = isect_range; +} + +void ShadowDirectional::end_sync(Light &light, const Camera &camera, float lod_bias) +{ + ShadowTileMapPool &tilemap_pool = shadows_.tilemap_pool; + IndexRange levels_new = directional_distribution_type_get(camera) == SHADOW_PROJECTION_CASCADE ? + cascade_level_range(camera, lod_bias) : + clipmap_level_range(camera); + + if (levels_range != levels_new) { + /* Acquire missing tile-maps. */ + IndexRange isect_range = levels_new.intersect(levels_range); + int64_t before_range = isect_range.start() - levels_new.start(); + int64_t after_range = levels_new.one_after_last() - isect_range.one_after_last(); + + Vector cached_tilemaps = tilemaps_; + tilemaps_.clear(); + for (int64_t i = 0; i < before_range; i++) { + tilemaps_.append(tilemap_pool.acquire()); + } + /* Keep cached LOD's. */ + tilemaps_.extend(cached_tilemaps); + for (int64_t i = 0; i < after_range; i++) { + tilemaps_.append(tilemap_pool.acquire()); + } + levels_range = levels_new; + } + + light.tilemap_index = tilemap_pool.tilemaps_data.size(); + light.clip_near = int(0xFF7FFFFFu ^ 0x7FFFFFFFu); /* floatBitsToOrderedInt(-FLT_MAX) */ + light.clip_far = 0x7F7FFFFF; /* floatBitsToOrderedInt(FLT_MAX) */ + + if (directional_distribution_type_get(camera) == SHADOW_PROJECTION_CASCADE) { + cascade_tilemaps_distribution(light, camera); + } + else { + clipmap_tilemaps_distribution(light, camera, lod_bias); + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shadow Module + * + * \{ */ + +ShadowModule::ShadowModule(Instance &inst) : inst_(inst) +{ + for (int i = 0; i < statistics_buf_.size(); i++) { + UNUSED_VARS(i); + statistics_buf_.current().clear_to_zero(); + statistics_buf_.swap(); + } +} + +void ShadowModule::init() +{ + ::Scene &scene = *inst_.scene; + bool enabled = (scene.eevee.flag & SCE_EEVEE_SHADOW_ENABLED) != 0; + if (assign_if_different(enabled_, enabled)) { + inst_.sampling.reset(); + /* Force light reset. */ + for (Light &light : inst_.lights.light_map_.values()) { + light.initialized = false; + } + } + + int pool_size = enabled_ ? scene.eevee.shadow_pool_size : 0; + shadow_page_len_ = clamp_i(pool_size * 4, SHADOW_PAGE_PER_ROW, SHADOW_MAX_PAGE); + + float simplify_shadows = 1.0f; + if (scene.r.mode & R_SIMPLIFY) { + simplify_shadows = inst_.is_viewport() ? scene.r.simplify_shadows : + scene.r.simplify_shadows_render; + } + lod_bias_ = math::interpolate(float(SHADOW_TILEMAP_LOD), 0.0f, simplify_shadows); + + int2 atlas_extent = shadow_page_size_ * + int2(SHADOW_PAGE_PER_ROW, shadow_page_len_ / SHADOW_PAGE_PER_ROW); + + eGPUTextureUsage tex_usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_SHADER_WRITE; + if (atlas_tx_.ensure_2d(atlas_type, atlas_extent, tex_usage)) { + /* Global update. */ + do_full_update = true; + } + + /* Make allocation safe. Avoids crash later on. */ + if (!atlas_tx_.is_valid()) { + atlas_tx_.ensure_2d(atlas_type, int2(1)); + inst_.info = "Error: Could not allocate shadow atlas. Most likely out of GPU memory."; + } + + /* Read end of the swap-chain to avoid stall. */ + { + if (inst_.sampling.finished_viewport()) { + /* Swap enough to read the last one. */ + for (int i = 0; i < statistics_buf_.size(); i++) { + statistics_buf_.swap(); + } + } + else { + statistics_buf_.swap(); + } + statistics_buf_.current().read(); + ShadowStatistics stats = statistics_buf_.current(); + + if (stats.page_used_count > shadow_page_len_ && enabled_) { + std::stringstream ss; + ss << "Error: Shadow buffer full, may result in missing shadows and lower performance. (" + << stats.page_used_count << " / " << shadow_page_len_ << ")\n"; + inst_.info = ss.str(); + } + } + + atlas_tx_.filter_mode(false); + + render_map_tx_.ensure_mip_views(); +} + +void ShadowModule::begin_sync() +{ + past_casters_updated_.clear(); + curr_casters_updated_.clear(); + curr_casters_.clear(); + + { + Manager &manager = *inst_.manager; + RenderBuffers &render_buffers = inst_.render_buffers; + + PassMain &pass = tilemap_usage_ps_; + pass.init(); + + { + /** Use depth buffer to tag needed shadow pages for opaque geometry. */ + PassMain::Sub &sub = pass.sub("Opaque"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_TAG_USAGE_OPAQUE)); + sub.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data); + sub.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data); + sub.bind_texture("depth_tx", &render_buffers.depth_tx); + sub.push_constant("tilemap_projection_ratio", &tilemap_projection_ratio_); + inst_.lights.bind_resources(&sub); + sub.dispatch(&dispatch_depth_scan_size_); + } + { + /** Use bounding boxes for transparent geometry. */ + PassMain::Sub &sub = pass.sub("Transparent"); + /* WORKAROUND: The DRW_STATE_WRITE_STENCIL is here only to avoid enabling the rasterizer + * discard inside draw manager. */ + sub.state_set(DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_STENCIL); + sub.state_stencil(0, 0, 0); + sub.framebuffer_set(&usage_tag_fb); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT)); + sub.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data); + sub.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data); + sub.bind_ssbo("bounds_buf", &manager.bounds_buf.current()); + sub.push_constant("tilemap_projection_ratio", &tilemap_projection_ratio_); + inst_.lights.bind_resources(&sub); + + box_batch_ = DRW_cache_cube_get(); + tilemap_usage_transparent_ps_ = ⊂ + } + } +} + +void ShadowModule::sync_object(const ObjectHandle &handle, + const ResourceHandle &resource_handle, + bool is_shadow_caster, + bool is_alpha_blend) +{ + if (!is_shadow_caster && !is_alpha_blend) { + return; + } + + ShadowObject &shadow_ob = objects_.lookup_or_add_default(handle.object_key); + shadow_ob.used = true; + const bool is_initialized = shadow_ob.resource_handle.raw != 0; + if ((handle.recalc != 0 || !is_initialized) && is_shadow_caster) { + if (shadow_ob.resource_handle.raw != 0) { + past_casters_updated_.append(shadow_ob.resource_handle.raw); + } + curr_casters_updated_.append(resource_handle.raw); + } + shadow_ob.resource_handle = resource_handle; + + if (is_shadow_caster) { + curr_casters_.append(resource_handle.raw); + } + + if (is_alpha_blend) { + tilemap_usage_transparent_ps_->draw(box_batch_, resource_handle); + } +} + +void ShadowModule::end_sync() +{ + /* Delete unused shadows first to release tile-maps that could be reused for new lights. */ + for (Light &light : inst_.lights.light_map_.values()) { + if (!light.used || !enabled_) { + light.shadow_discard_safe(*this); + } + else if (light.directional != nullptr) { + light.directional->release_excess_tilemaps(inst_.camera, lod_bias_); + } + else if (light.punctual != nullptr) { + light.punctual->release_excess_tilemaps(); + } + } + + /* Allocate new tile-maps and fill shadow data of the lights. */ + tilemap_pool.tilemaps_data.clear(); + for (Light &light : inst_.lights.light_map_.values()) { + if (light.directional != nullptr) { + light.directional->end_sync(light, inst_.camera, lod_bias_); + } + else if (light.punctual != nullptr) { + light.punctual->end_sync(light, lod_bias_); + } + else { + light.tilemap_index = LIGHT_NO_SHADOW; + } + } + tilemap_pool.end_sync(*this); + + /* Search for deleted or updated shadow casters */ + auto it_end = objects_.items().end(); + for (auto it = objects_.items().begin(); it != it_end; ++it) { + ShadowObject &shadow_ob = (*it).value; + if (!shadow_ob.used) { + /* May not be a caster, but it does not matter, be conservative. */ + past_casters_updated_.append(shadow_ob.resource_handle.raw); + objects_.remove(it); + } + else { + /* Clear for next sync. */ + shadow_ob.used = false; + } + } + if (!past_casters_updated_.is_empty() || !curr_casters_updated_.is_empty()) { + inst_.sampling.reset(); + } + past_casters_updated_.push_update(); + curr_casters_updated_.push_update(); + + curr_casters_.push_update(); + + if (do_full_update) { + do_full_update = false; + /* Put all pages in the free heap. */ + for (uint i : IndexRange(shadow_page_len_)) { + uint2 page = {i % SHADOW_PAGE_PER_ROW, i / SHADOW_PAGE_PER_ROW}; + pages_free_data_[i] = page.x | (page.y << 16u); + } + pages_free_data_.push_update(); + + /* Clear tiles to not reference any page. */ + tilemap_pool.tiles_data.clear_to_zero(); + + /* Clear tile-map clip buffer. */ + union { + ShadowTileMapClip clip; + int4 i; + } u; + u.clip.clip_near_stored = 0.0f; + u.clip.clip_far_stored = 0.0f; + u.clip.clip_near = int(0xFF7FFFFFu ^ 0x7FFFFFFFu); /* floatBitsToOrderedInt(-FLT_MAX) */ + u.clip.clip_far = 0x7F7FFFFF; /* floatBitsToOrderedInt(FLT_MAX) */ + GPU_storagebuf_clear(tilemap_pool.tilemaps_clip, GPU_RGBA32I, GPU_DATA_INT, &u.i); + + /* Clear cached page buffer. */ + int2 data = {-1, -1}; + GPU_storagebuf_clear(pages_cached_data_, GPU_RG32I, GPU_DATA_INT, &data); + + /* Reset info to match new state. */ + pages_infos_data_.page_free_count = shadow_page_len_; + pages_infos_data_.page_alloc_count = 0; + pages_infos_data_.page_cached_next = 0u; + pages_infos_data_.page_cached_start = 0u; + pages_infos_data_.page_cached_end = 0u; + pages_infos_data_.page_size = shadow_page_size_; + pages_infos_data_.push_update(); + } + + { + Manager &manager = *inst_.manager; + + { + PassSimple &pass = tilemap_setup_ps_; + pass.init(); + + { + /** Compute near/far clip distances for directional shadows based on casters bounds. */ + PassSimple::Sub &sub = pass.sub("DirectionalBounds"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_BOUNDS)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tilemaps_clip_buf", tilemap_pool.tilemaps_clip); + sub.bind_ssbo("casters_id_buf", curr_casters_); + sub.bind_ssbo("bounds_buf", &manager.bounds_buf.current()); + sub.push_constant("resource_len", int(curr_casters_.size())); + inst_.lights.bind_resources(&sub); + sub.dispatch(int3(divide_ceil_u(curr_casters_.size(), SHADOW_BOUNDS_GROUP_SIZE), 1, 1)); + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { + /** Clear usage bits. Tag update from the tile-map for sun shadow clip-maps shifting. */ + PassSimple::Sub &sub = pass.sub("Init"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_INIT)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tilemaps_clip_buf", tilemap_pool.tilemaps_clip); + sub.bind_ssbo("tiles_buf", tilemap_pool.tiles_data); + sub.bind_ssbo("pages_cached_buf", pages_cached_data_); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size())); + /** Free unused tiles from tile-maps not used by any shadow. */ + if (tilemap_pool.tilemaps_unused.size() > 0) { + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_unused); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_unused.size())); + } + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { + /** Mark for update all shadow pages touching an updated shadow caster. */ + PassSimple::Sub &sub = pass.sub("CasterUpdate"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_TAG_UPDATE)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tiles_buf", tilemap_pool.tiles_data); + /* Past caster transforms. */ + if (past_casters_updated_.size() > 0) { + sub.bind_ssbo("bounds_buf", &manager.bounds_buf.previous()); + sub.bind_ssbo("resource_ids_buf", past_casters_updated_); + sub.dispatch(int3(past_casters_updated_.size(), 1, tilemap_pool.tilemaps_data.size())); + } + /* Current caster transforms. */ + if (curr_casters_updated_.size() > 0) { + sub.bind_ssbo("bounds_buf", &manager.bounds_buf.current()); + sub.bind_ssbo("resource_ids_buf", curr_casters_updated_); + sub.dispatch(int3(curr_casters_updated_.size(), 1, tilemap_pool.tilemaps_data.size())); + } + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + } + + /* Usage tagging happens between these two steps. */ + + { + PassSimple &pass = tilemap_update_ps_; + pass.init(); + { + /** Mark tiles that are redundant in the mipmap chain as unused. */ + PassSimple::Sub &sub = pass.sub("MaskLod"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_PAGE_MASK)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tiles_buf", tilemap_pool.tiles_data); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size())); + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { + /** Free unused pages & Reclaim cached pages. */ + PassSimple::Sub &sub = pass.sub("Free"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_PAGE_FREE)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tiles_buf", tilemap_pool.tiles_data); + sub.bind_ssbo("pages_infos_buf", pages_infos_data_); + sub.bind_ssbo("pages_free_buf", pages_free_data_); + sub.bind_ssbo("pages_cached_buf", pages_cached_data_); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size())); + /** Free unused tiles from tile-maps not used by any shadow. */ + if (tilemap_pool.tilemaps_unused.size() > 0) { + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_unused); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_unused.size())); + } + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { + /** De-fragment the free page heap after cache reuse phase which can leave hole. */ + PassSimple::Sub &sub = pass.sub("Defrag"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_PAGE_DEFRAG)); + sub.bind_ssbo("pages_infos_buf", pages_infos_data_); + sub.bind_ssbo("pages_free_buf", pages_free_data_); + sub.bind_ssbo("pages_cached_buf", pages_cached_data_); + sub.bind_ssbo("statistics_buf", statistics_buf_.current()); + sub.bind_ssbo("clear_dispatch_buf", clear_dispatch_buf_); + sub.dispatch(int3(1, 1, 1)); + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { + /** Assign pages to tiles that have been marked as used but possess no page. */ + PassSimple::Sub &sub = pass.sub("AllocatePages"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_PAGE_ALLOCATE)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tiles_buf", tilemap_pool.tiles_data); + sub.bind_ssbo("statistics_buf", statistics_buf_.current()); + sub.bind_ssbo("pages_infos_buf", pages_infos_data_); + sub.bind_ssbo("pages_free_buf", pages_free_data_); + sub.bind_ssbo("pages_cached_buf", pages_cached_data_); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size())); + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { + /** Convert the unordered tiles into a texture used during shading. Creates views. */ + PassSimple::Sub &sub = pass.sub("Finalize"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_FINALIZE)); + sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data); + sub.bind_ssbo("tilemaps_clip_buf", tilemap_pool.tilemaps_clip); + sub.bind_ssbo("tiles_buf", tilemap_pool.tiles_data); + sub.bind_ssbo("view_infos_buf", &shadow_multi_view_.matrices_ubo_get()); + sub.bind_ssbo("statistics_buf", statistics_buf_.current()); + sub.bind_ssbo("clear_dispatch_buf", clear_dispatch_buf_); + sub.bind_ssbo("clear_page_buf", clear_page_buf_); + sub.bind_ssbo("pages_infos_buf", pages_infos_data_); + sub.bind_image("tilemaps_img", tilemap_pool.tilemap_tx); + sub.bind_image("render_map_lod0_img", render_map_tx_.mip_view(0)); + sub.bind_image("render_map_lod1_img", render_map_tx_.mip_view(1)); + sub.bind_image("render_map_lod2_img", render_map_tx_.mip_view(2)); + sub.bind_image("render_map_lod3_img", render_map_tx_.mip_view(3)); + sub.bind_image("render_map_lod4_img", render_map_tx_.mip_view(4)); + sub.bind_image("render_map_lod5_img", render_map_tx_.mip_view(5)); + sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size())); + sub.barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_UNIFORM | GPU_BARRIER_TEXTURE_FETCH | + GPU_BARRIER_SHADER_IMAGE_ACCESS); + } + { + /** Clear pages that need to be rendered. */ + PassSimple::Sub &sub = pass.sub("RenderClear"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_PAGE_CLEAR)); + sub.bind_ssbo("pages_infos_buf", pages_infos_data_); + sub.bind_ssbo("clear_dispatch_buf", clear_dispatch_buf_); + sub.bind_image("atlas_img", atlas_tx_); + sub.dispatch(clear_dispatch_buf_); + sub.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS); + } + } + } + + debug_end_sync(); +} + +void ShadowModule::debug_end_sync() +{ + if (!ELEM(inst_.debug_mode, + eDebugMode::DEBUG_SHADOW_TILEMAPS, + eDebugMode::DEBUG_SHADOW_VALUES, + eDebugMode::DEBUG_SHADOW_TILE_RANDOM_COLOR, + eDebugMode::DEBUG_SHADOW_TILEMAP_RANDOM_COLOR)) { + return; + } + + /* Init but not filled if no active object. */ + debug_draw_ps_.init(); + + Object *object_active = DRW_context_state_get()->obact; + if (object_active == nullptr) { + return; + } + + ObjectKey object_key(DEG_get_original_object(object_active)); + + if (inst_.lights.light_map_.contains(object_key) == false) { + return; + } + + Light &light = inst_.lights.light_map_.lookup(object_key); + + if (light.tilemap_index >= SHADOW_MAX_TILEMAP) { + return; + } + + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | + DRW_STATE_BLEND_CUSTOM; + + debug_draw_ps_.state_set(state); + debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(SHADOW_DEBUG)); + debug_draw_ps_.push_constant("debug_mode", int(inst_.debug_mode)); + debug_draw_ps_.push_constant("debug_tilemap_index", light.tilemap_index); + debug_draw_ps_.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data); + debug_draw_ps_.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data); + inst_.hiz_buffer.bind_resources(&debug_draw_ps_); + inst_.lights.bind_resources(&debug_draw_ps_); + inst_.shadows.bind_resources(&debug_draw_ps_); + debug_draw_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); +} + +/* Compute approximate screen pixel density (as world space radius). */ +float ShadowModule::screen_pixel_radius(const View &view, const int2 &extent) +{ + float min_dim = float(min_ii(extent.x, extent.y)); + float3 p0 = float3(-1.0f, -1.0f, 0.0f); + float3 p1 = float3(float2(min_dim / extent) * 2.0f - 1.0f, 0.0f); + mul_project_m4_v3(view.wininv().ptr(), p0); + mul_project_m4_v3(view.wininv().ptr(), p1); + /* Compute radius at unit plane from the camera. This is NOT the perspective division. */ + if (view.is_persp()) { + p0 = p0 / p0.z; + p1 = p1 / p1.z; + } + return math::distance(p0, p1) / min_dim; +} + +/* Compute approximate screen pixel world space radius at 1 unit away of the light. */ +float ShadowModule::tilemap_pixel_radius() +{ + /* This is a really rough approximation. Ideally, the cube-map distortion should be taken into + * account per pixel. But this would make this pre-computation impossible. + * So for now compute for the center of the cube-map. */ + const float cubeface_diagonal = M_SQRT2 * 2.0f; + const float pixel_count = SHADOW_TILEMAP_RES * shadow_page_size_; + return cubeface_diagonal / pixel_count; +} + +/* Update all shadow regions visible inside the view. + * If called multiple time for the same view, it will only do the depth buffer scanning + * to check any new opaque surfaces. + * Needs to be called after LightModule::set_view(); */ +void ShadowModule::set_view(View &view) +{ + GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); + + int3 target_size = inst_.render_buffers.depth_tx.size(); + dispatch_depth_scan_size_ = math::divide_ceil(target_size, int3(SHADOW_DEPTH_SCAN_GROUP_SIZE)); + + tilemap_projection_ratio_ = tilemap_pixel_radius() / + screen_pixel_radius(view, int2(target_size)); + + usage_tag_fb.ensure(int2(target_size)); + render_fb_.ensure(int2(SHADOW_TILEMAP_RES * shadow_page_size_)); + + bool tile_update_remains = true; + while (tile_update_remains) { + DRW_stats_group_start("Shadow"); + { + GPU_uniformbuf_clear_to_zero(shadow_multi_view_.matrices_ubo_get()); + + inst_.manager->submit(tilemap_setup_ps_, view); + + inst_.manager->submit(tilemap_usage_ps_, view); + + inst_.manager->submit(tilemap_update_ps_, view); + + shadow_multi_view_.compute_procedural_bounds(); + + inst_.pipelines.shadow.render(shadow_multi_view_); + } + DRW_stats_group_end(); + + if (inst_.is_viewport()) { + tile_update_remains = false; + } + else { + /* This provoke a GPU/CPU sync. Avoid it if we are sure that all tile-maps will be rendered + * in a single iteration. */ + bool enough_tilemap_for_single_iteration = tilemap_pool.tilemaps_data.size() <= + SHADOW_VIEW_MAX; + if (enough_tilemap_for_single_iteration) { + tile_update_remains = false; + } + else { + /* Read back and check if there is still tile-map to update. */ + tile_update_remains = false; + statistics_buf_.current().read(); + ShadowStatistics stats = statistics_buf_.current(); + tile_update_remains = stats.page_rendered_count < stats.page_update_count; + } + } + } + + if (prev_fb) { + GPU_framebuffer_bind(prev_fb); + } +} + +void ShadowModule::debug_draw(View &view, GPUFrameBuffer *view_fb) +{ + if (!ELEM(inst_.debug_mode, + eDebugMode::DEBUG_SHADOW_TILEMAPS, + eDebugMode::DEBUG_SHADOW_VALUES, + eDebugMode::DEBUG_SHADOW_TILE_RANDOM_COLOR, + eDebugMode::DEBUG_SHADOW_TILEMAP_RANDOM_COLOR)) { + return; + } + + switch (inst_.debug_mode) { + case DEBUG_SHADOW_TILEMAPS: + inst_.info = "Debug Mode: Shadow Tilemap\n"; + break; + case DEBUG_SHADOW_VALUES: + inst_.info = "Debug Mode: Shadow Values\n"; + break; + case DEBUG_SHADOW_TILE_RANDOM_COLOR: + inst_.info = "Debug Mode: Shadow Tile Random Color\n"; + break; + case DEBUG_SHADOW_TILEMAP_RANDOM_COLOR: + inst_.info = "Debug Mode: Shadow Tilemap Random Color\n"; + break; + default: + break; + } + + inst_.hiz_buffer.update(); + + GPU_framebuffer_bind(view_fb); + inst_.manager->submit(debug_draw_ps_, view); +} + +/** \} */ + +} // namespace blender::eevee diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.hh b/source/blender/draw/engines/eevee_next/eevee_shadow.hh new file mode 100644 index 00000000000..5106bac7b18 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.hh @@ -0,0 +1,451 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. + */ + +/** \file + * \ingroup eevee + * + * The shadow module manages shadow update tagging & shadow rendering. + */ + +#pragma once + +#include "BLI_pool.hh" +#include "BLI_vector.hh" + +#include "GPU_batch.h" + +#include "eevee_material.hh" +#include "eevee_shader.hh" +#include "eevee_shader_shared.hh" + +namespace blender::eevee { + +class Instance; +class ShadowModule; +class ShadowPipeline; +struct Light; + +enum eCubeFace { + /* Ordering by culling order. If cone aperture is shallow, we cull the later view. */ + Z_NEG = 0, + X_POS, + X_NEG, + Y_POS, + Y_NEG, + Z_POS, +}; + +/* To be applied after view matrix. Follow same order as eCubeFace. */ +constexpr static const float shadow_face_mat[6][4][4] = { + {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}, /* Z_NEG */ + {{0, 0, -1, 0}, {-1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}, /* X_POS */ + {{0, 0, 1, 0}, {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}, /* X_NEG */ + {{1, 0, 0, 0}, {0, 0, -1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}, /* Y_POS */ + {{-1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}, /* Y_NEG */ + {{1, 0, 0, 0}, {0, -1, 0, 0}, {0, 0, -1, 0}, {0, 0, 0, 1}}, /* Z_POS */ +}; + +/* Converts to [-SHADOW_TILEMAP_RES / 2..SHADOW_TILEMAP_RES / 2] for XY and [0..1] for Z. */ +constexpr static const float shadow_clipmap_scale_mat[4][4] = {{SHADOW_TILEMAP_RES / 2, 0, 0, 0}, + {0, SHADOW_TILEMAP_RES / 2, 0, 0}, + {0, 0, 0.5, 0}, + {0, 0, 0.5, 1}}; + +/* -------------------------------------------------------------------- */ +/** \name Tile-Map + * + * Stores indirection table and states of each tile of a virtual shadow-map. + * One tile-map has the effective resolution of `pagesize * tile_map_resolution`. + * Each tile-map overhead is quite small if they do not have any pages allocated. + * + * \{ */ + +struct ShadowTileMap : public ShadowTileMapData { + static constexpr int64_t tile_map_resolution = SHADOW_TILEMAP_RES; + static constexpr int64_t tiles_count = tile_map_resolution * tile_map_resolution; + + /** Level of detail for clipmap. */ + int level = INT_MAX; + /** Cube face index. */ + eCubeFace cubeface = Z_NEG; + /** Cached, used for detecting updates. */ + float4x4 object_mat; + /** Near and far clip distances. For clip-map, computed on the GPU using casters BBoxes. */ + float near, far; + + public: + ShadowTileMap(int tiles_index_) + { + tiles_index = tiles_index_; + /* For now just the same index. */ + clip_data_index = tiles_index_ / SHADOW_TILEDATA_PER_TILEMAP; + this->set_dirty(); + } + + void sync_orthographic(const float4x4 &object_mat_, + int2 origin_offset, + int clipmap_level, + float lod_bias_, + eShadowProjectionType projection_type_); + + void sync_cubeface( + const float4x4 &object_mat, float near, float far, eCubeFace face, float lod_bias_); + + void debug_draw() const; + + void set_dirty() + { + grid_shift = int2(SHADOW_TILEMAP_RES); + } + + void set_updated() + { + grid_shift = int2(0); + } +}; + +/** + * The tile-maps are managed on CPU and associated with each light shadow object. + * + * The number of tile-maps & tiles is unbounded (to the limit of SSBOs), but the actual number + * used for rendering is caped to 4096. This is to simplify tile-maps management on CPU. + * + * At sync end, all tile-maps are grouped by light inside the ShadowTileMapDataBuf so that each + * light has a contiguous range of tile-maps to refer to. + */ +struct ShadowTileMapPool { + public: + /** Limit the width of the texture. */ + static constexpr int64_t maps_per_row = SHADOW_TILEMAP_PER_ROW; + + /** Vector containing available offset to tile range in the ShadowTileDataBuf. */ + Vector free_indices; + /** Pool containing shadow tile structure on CPU. */ + Pool tilemap_pool; + /** Sorted descriptions for each tile-map in the pool. Updated each frame. */ + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + /** Previously used tile-maps that needs to release their tiles/pages. Updated each frame. */ + ShadowTileMapDataBuf tilemaps_unused = {"tilemaps_unused"}; + /** All possible tiles. A range of tiles tile is referenced by a tile-map. */ + ShadowTileDataBuf tiles_data = {"tiles_data"}; + /** Clip range for directional shadows. Updated on GPU. Persistent. */ + ShadowTileMapClipBuf tilemaps_clip = {"tilemaps_clip"}; + /** Texture equivalent of ShadowTileDataBuf but grouped by light. */ + Texture tilemap_tx = {"tilemap_tx"}; + /** Number of free tile-maps at the end of the previous sync. */ + int64_t last_free_len = 0; + + public: + ShadowTileMapPool(); + + ShadowTileMap *acquire(); + + /** + * Push the given list of ShadowTileMap onto the free stack. Their pages will be free. + */ + void release(Span free_list); + + void end_sync(ShadowModule &module); +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shadow Casters & Receivers + * + * \{ */ + +/* Can be either a shadow caster or a shadow receiver. */ +struct ShadowObject { + ResourceHandle resource_handle = {0}; + bool used = true; +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name ShadowModule + * + * Manages shadow atlas and shadow region data. + * \{ */ + +class ShadowModule { + friend ShadowPunctual; + friend ShadowDirectional; + friend ShadowPipeline; + friend ShadowTileMapPool; + + public: + /** Need to be first because of destructor order. */ + ShadowTileMapPool tilemap_pool; + + Pool punctual_pool; + Pool directional_pool; + + private: + Instance &inst_; + + /** Map of shadow casters to track deletion & update of intersected shadows. */ + Map objects_; + + /* -------------------------------------------------------------------- */ + /** \name Tile-map Management + * \{ */ + + PassSimple tilemap_setup_ps_ = {"TilemapSetup"}; + PassMain tilemap_usage_ps_ = {"TagUsage"}; + PassSimple tilemap_update_ps_ = {"TilemapUpdate"}; + + PassMain::Sub *tilemap_usage_transparent_ps_ = nullptr; + GPUBatch *box_batch_ = nullptr; + + Framebuffer usage_tag_fb; + + /** List of Resource IDs (to get bounds) for tagging passes. */ + StorageVectorBuffer past_casters_updated_ = {"PastCastersUpdated"}; + StorageVectorBuffer curr_casters_updated_ = {"CurrCastersUpdated"}; + /** List of Resource IDs (to get bounds) for getting minimum clip-maps bounds. */ + StorageVectorBuffer curr_casters_ = {"CurrCasters"}; + + /** Indirect arguments for page clearing. */ + StorageBuffer clear_dispatch_buf_; + /** Pages to clear. */ + StorageArrayBuffer clear_page_buf_ = {"clear_page_buf"}; + + int3 dispatch_depth_scan_size_; + /* Ratio between tile-map pixel world "radius" and film pixel world "radius". */ + float tilemap_projection_ratio_; + + /* Statistics that are read back to CPU after a few frame (to avoid stall). */ + SwapChain statistics_buf_; + + /** \} */ + + /* -------------------------------------------------------------------- */ + /** \name Page Management + * \{ */ + + static constexpr eGPUTextureFormat atlas_type = GPU_R32UI; + /** Atlas containing all physical pages. */ + Texture atlas_tx_ = {"shadow_atlas_tx_"}; + + /** Pool of unallocated pages waiting to be assigned to specific tiles in the tile-map atlas. */ + ShadowPageHeapBuf pages_free_data_ = {"PagesFreeBuf"}; + /** Pool of cached tiles waiting to be reused. */ + ShadowPageCacheBuf pages_cached_data_ = {"PagesCachedBuf"}; + /** Infos for book keeping and debug. */ + ShadowPagesInfoDataBuf pages_infos_data_ = {"PagesInfosBuf"}; + + int3 copy_dispatch_size_; + int3 scan_dispatch_size_; + int rendering_tilemap_; + int rendering_lod_; + bool do_full_update = true; + + /** \} */ + + /* -------------------------------------------------------------------- */ + /** \name Rendering + * \{ */ + + /** Multi-View containing a maximum of 64 view to be rendered with the shadow pipeline. */ + View shadow_multi_view_ = {"ShadowMultiView", SHADOW_VIEW_MAX, true}; + /** Tile to physical page mapping. This is an array texture with one layer per view. */ + Texture render_map_tx_ = {"ShadowRenderMap", + GPU_R32UI, + GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_SHADER_WRITE, + int2(SHADOW_TILEMAP_RES), + 64, + nullptr, + SHADOW_TILEMAP_LOD + 1}; + /** An empty frame-buffer (no attachment) the size of a whole tile-map. */ + Framebuffer render_fb_; + + /** \} */ + + /* -------------------------------------------------------------------- */ + /** \name Debugging + * \{ */ + + /** Display information about the virtual shadows. */ + PassSimple debug_draw_ps_ = {"Shadow.Debug"}; + + /** \} */ + + /** Scene immutable parameters. */ + + /** For now, needs to be hardcoded. */ + int shadow_page_size_ = SHADOW_PAGE_RES; + /** Amount of bias to apply to the LOD computed at the tile usage tagging stage. */ + float lod_bias_ = 0.0f; + /** Maximum number of allocated pages. Maximum value is SHADOW_MAX_TILEMAP. */ + int shadow_page_len_ = SHADOW_MAX_TILEMAP; + /** Global switch. */ + bool enabled_ = true; + + public: + ShadowModule(Instance &inst); + ~ShadowModule(){}; + + void init(); + + void begin_sync(); + /** Register a shadow caster or receiver. */ + void sync_object(const ObjectHandle &handle, + const ResourceHandle &resource_handle, + bool is_shadow_caster, + bool is_alpha_blend); + void end_sync(); + + void set_lights_data(); + + void set_view(View &view); + + void debug_end_sync(); + void debug_draw(View &view, GPUFrameBuffer *view_fb); + + template void bind_resources(draw::detail::PassBase *pass) + { + pass->bind_texture(SHADOW_ATLAS_TEX_SLOT, &atlas_tx_); + pass->bind_texture(SHADOW_TILEMAPS_TEX_SLOT, &tilemap_pool.tilemap_tx); + } + + private: + void remove_unused(); + void debug_page_map_call(DRWPass *pass); + + /** Compute approximate screen pixel space radius. */ + float screen_pixel_radius(const View &view, const int2 &extent); + /** Compute approximate punctual shadow pixel world space radius, 1 unit away of the light. */ + float tilemap_pixel_radius(); +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shadow + * + * A shadow component is associated to a `eevee::Light` and manages its associated Tile-maps. + * \{ */ + +class ShadowPunctual : public NonCopyable, NonMovable { + private: + ShadowModule &shadows_; + /** Tile-map for each cube-face needed (in eCubeFace order). */ + Vector tilemaps_; + /** Area light size. */ + float size_x_, size_y_; + /** Shape type. */ + eLightType light_type_; + /** Random position on the light. In world space. */ + float3 random_offset_; + /** Light position. */ + float3 position_; + /** Near and far clip distances. */ + float far_, near_; + /** Number of tile-maps needed to cover the light angular extents. */ + int tilemaps_needed_; + /** Visibility cone angle from the light source. */ + int cone_aperture_; + + public: + ShadowPunctual(ShadowModule &module) : shadows_(module){}; + ShadowPunctual(ShadowPunctual &&other) + : shadows_(other.shadows_), tilemaps_(std::move(other.tilemaps_)){}; + + ~ShadowPunctual() + { + shadows_.tilemap_pool.release(tilemaps_); + } + + /** + * Sync shadow parameters but do not allocate any shadow tile-maps. + */ + void sync(eLightType light_type, + const float4x4 &object_mat, + float cone_aperture, + float near_clip, + float far_clip); + + /** + * Release the tile-maps that will not be used in the current frame. + */ + void release_excess_tilemaps(); + + /** + * Allocate shadow tile-maps and setup views for rendering. + */ + void end_sync(Light &light, float lod_bias); +}; + +class ShadowDirectional : public NonCopyable, NonMovable { + private: + ShadowModule &shadows_; + /** Tile-map for each clip-map level. */ + Vector tilemaps_; + /** User minimum resolution. */ + float min_resolution_; + /** Copy of object matrix. Normalized. */ + float4x4 object_mat_; + /** Current range of clip-map / cascades levels covered by this shadow. */ + IndexRange levels_range; + + public: + ShadowDirectional(ShadowModule &module) : shadows_(module){}; + ShadowDirectional(ShadowDirectional &&other) + : shadows_(other.shadows_), tilemaps_(std::move(other.tilemaps_)){}; + + ~ShadowDirectional() + { + shadows_.tilemap_pool.release(tilemaps_); + } + + /** + * Sync shadow parameters but do not allocate any shadow tile-maps. + */ + void sync(const float4x4 &object_mat, float min_resolution); + + /** + * Release the tile-maps that will not be used in the current frame. + */ + void release_excess_tilemaps(const Camera &camera, float lod_bias); + + /** + * Allocate shadow tile-maps and setup views for rendering. + */ + void end_sync(Light &light, const Camera &camera, float lod_bias); + + /* Return coverage of the whole tile-map in world unit. */ + static float coverage_get(int lvl) + { + /* This function should be kept in sync with shadow_directional_level(). */ + /* \note: If we would to introduce a global scaling option it would be here. */ + return exp2(lvl); + } + + /* Return coverage of a single tile for a tile-map of this LOD in world unit. */ + static float tile_size_get(int lvl) + { + return coverage_get(lvl) / SHADOW_TILEMAP_RES; + } + + private: + IndexRange clipmap_level_range(const Camera &camera); + IndexRange cascade_level_range(const Camera &camera, float lod_bias); + + void cascade_tilemaps_distribution(Light &light, const Camera &camera); + void clipmap_tilemaps_distribution(Light &light, const Camera &camera, float lod_bias); + + void cascade_tilemaps_distribution_near_far_points(const Camera &camera, + float3 &near_point, + float3 &far_point); + + /* Choose between clip-map and cascade distribution of shadow-map precision depending on the + * camera projection type and bounds. */ + static eShadowProjectionType directional_distribution_type_get(const Camera &camera); +}; + +/** \} */ + +} // namespace blender::eevee diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.cc b/source/blender/draw/engines/eevee_next/eevee_sync.cc index cbd735ec29c..fa09edce8d4 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sync.cc +++ b/source/blender/draw/engines/eevee_next/eevee_sync.cc @@ -41,6 +41,7 @@ ObjectHandle &SyncModule::sync_object(Object *ob) ObjectHandle &eevee_dd = *reinterpret_cast(dd); if (eevee_dd.object_key.ob == nullptr) { + ob = DEG_get_original_object(ob); eevee_dd.object_key = ObjectKey(ob); } @@ -48,7 +49,6 @@ ObjectHandle &SyncModule::sync_object(Object *ob) ID_RECALC_GEOMETRY; if ((eevee_dd.recalc & recalc_flags) != 0) { inst_.sampling.reset(); - UNUSED_VARS(inst_); } return eevee_dd; @@ -127,13 +127,13 @@ void SyncModule::sync_mesh(Object *ob, if (geom == nullptr) { continue; } - Material *material = material_array.materials[i]; - geometry_call(material->shading.sub_pass, geom, res_handle); - geometry_call(material->prepass.sub_pass, geom, res_handle); - geometry_call(material->shadow.sub_pass, geom, res_handle); + Material &material = material_array.materials[i]; + geometry_call(material.shading.sub_pass, geom, res_handle); + geometry_call(material.prepass.sub_pass, geom, res_handle); + geometry_call(material.shadow.sub_pass, geom, res_handle); - is_shadow_caster = is_shadow_caster || material->shadow.sub_pass != nullptr; - is_alpha_blend = is_alpha_blend || material->is_alpha_blend_transparent; + is_shadow_caster = is_shadow_caster || material.shadow.sub_pass != nullptr; + is_alpha_blend = is_alpha_blend || material.is_alpha_blend_transparent; GPUMaterial *gpu_material = material_array.gpu_materials[i]; ::Material *mat = GPU_material_get_material(gpu_material); @@ -141,8 +141,9 @@ void SyncModule::sync_mesh(Object *ob, } inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials); + + inst_.shadows.sync_object(ob_handle, res_handle, is_shadow_caster, is_alpha_blend); inst_.cryptomatte.sync_object(ob, res_handle); - // shadows.sync_object(ob, ob_handle, is_shadow_caster, is_alpha_blend); } /** \} */ @@ -236,7 +237,7 @@ static void gpencil_stroke_sync(bGPDlayer * /*gpl*/, { gpIterData &iter = *(gpIterData *)thunk; - Material *material = iter.material_array.materials[gps->mat_nr]; + Material *material = &iter.material_array.materials[gps->mat_nr]; MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(iter.ob, gps->mat_nr + 1); bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0; @@ -280,9 +281,9 @@ void SyncModule::sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandl gpencil_drawcall_flush(iter); - // bool is_caster = true; /* TODO material.shadow.sub_pass. */ - // bool is_alpha_blend = true; /* TODO material.is_alpha_blend. */ - // shadows.sync_object(ob, ob_handle, is_caster, is_alpha_blend); + bool is_caster = true; /* TODO material.shadow.sub_pass. */ + bool is_alpha_blend = true; /* TODO material.is_alpha_blend. */ + inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend); } /** \} */ @@ -347,9 +348,9 @@ void SyncModule::sync_curves(Object *ob, /* TODO(fclem) Hair velocity. */ // shading_passes.velocity.gpencil_add(ob, ob_handle); - // bool is_caster = material.shadow.sub_pass != nullptr; - // bool is_alpha_blend = material.is_alpha_blend_transparent; - // shadows.sync_object(ob, ob_handle, is_caster, is_alpha_blend); + bool is_caster = material.shadow.sub_pass != nullptr; + bool is_alpha_blend = material.is_alpha_blend_transparent; + inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend); } /** \} */ diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc index f3d645293db..87684b42ddf 100644 --- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc +++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc @@ -261,7 +261,7 @@ void VelocityModule::end_sync() { Vector deleted_obj; - uint32_t max_resource_id_ = 0u; + uint32_t max_resource_id_ = 1u; for (Map::Item item : velocity_map.items()) { if (item.value.obj.resource_id == uint32_t(-1)) { diff --git a/source/blender/draw/engines/eevee_next/eevee_view.cc b/source/blender/draw/engines/eevee_next/eevee_view.cc index 3a4fb9d4c20..d7cb4985a9b 100644 --- a/source/blender/draw/engines/eevee_next/eevee_view.cc +++ b/source/blender/draw/engines/eevee_next/eevee_view.cc @@ -134,13 +134,12 @@ void ShadingView::render() inst_.lights.debug_draw(render_view_new_, combined_fb_); inst_.hiz_buffer.debug_draw(render_view_new_, combined_fb_); + inst_.shadows.debug_draw(render_view_new_, combined_fb_); GPUTexture *combined_final_tx = render_postfx(rbufs.combined_tx); inst_.film.accumulate(sub_view_, combined_final_tx); - // inst_.shadows.debug_draw(); - rbufs.release(); postfx_tx_.release(); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl index f3bb1e2f490..c845d3f1ef5 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl @@ -16,6 +16,7 @@ # ifdef OBINFO_LIB vec3 attr_load_orco(vec4 orco) { +# ifdef GPU_VERTEX_SHADER /* We know when there is no orco layer when orco.w is 1.0 because it uses the generic vertex * attribute (which is [0,0,0,1]). */ if (orco.w == 1.0) { @@ -23,6 +24,7 @@ vec3 attr_load_orco(vec4 orco) * using the orco_madd factors. */ return OrcoTexCoFactors[0].xyz + pos * OrcoTexCoFactors[1].xyz; } +# endif return orco.xyz * 0.5 + 0.5; } # endif diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl index 87154ba6db1..875f0db347c 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl @@ -9,6 +9,11 @@ void main() { + DRW_VIEW_FROM_RESOURCE_ID; +#ifdef MAT_SHADOW + shadow_interp.view_id = drw_view_id; +#endif + init_interface(); vec3 T; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl index 87a5bf71c45..868d7a0cc3e 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl @@ -7,6 +7,11 @@ void main() { + DRW_VIEW_FROM_RESOURCE_ID; +#ifdef MAT_SHADOW + shadow_interp.view_id = drw_view_id; +#endif + init_interface(); /* TODO(fclem): Expose through a node? */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl index c07a8ae0eea..1f62f7a4e25 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl @@ -7,6 +7,11 @@ void main() { + DRW_VIEW_FROM_RESOURCE_ID; +#ifdef MAT_SHADOW + shadow_interp.view_id = drw_view_id; +#endif + init_interface(); interp.P = point_object_to_world(pos); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_select_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_select_comp.glsl index 9c12b0e50e6..58cb1540bd6 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_select_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_select_comp.glsl @@ -22,7 +22,7 @@ void main() } /* Sun lights are packed at the end of the array. Perform early copy. */ - if (light.type == LIGHT_SUN) { + if (is_sun_light(light.type)) { /* NOTE: We know the index because sun lights are packed at the start of the input buffer. */ out_light_buf[light_cull_buf.local_lights_len + l_idx] = light; return; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl index d4abdd43aa4..4a57a850d34 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl @@ -12,6 +12,7 @@ */ #pragma BLENDER_REQUIRE(eevee_light_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_lib.glsl) #pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl) /* TODO(fclem): We could reduce register pressure by only having static branches for sun lights. */ @@ -19,6 +20,7 @@ void light_eval_ex(ClosureDiffuse diffuse, ClosureReflection reflection, const bool is_directional, vec3 P, + vec3 Ng, vec3 V, float vP_z, float thickness, @@ -34,17 +36,17 @@ void light_eval_ex(ClosureDiffuse diffuse, float visibility = light_attenuation(light, L, dist); -#if 0 /* TODO(fclem): Shadows */ - if ((light.shadow_id != LIGHT_NO_SHADOW) && (visibility > 0.0)) { + if (light.tilemap_index != LIGHT_NO_SHADOW && (visibility > 0.0)) { vec3 lL = light_world_to_local(light, -L) * dist; + vec3 lNg = light_world_to_local(light, Ng); - float shadow_delta = shadow_delta_get( - shadow_atlas_tx, shadow_tilemaps_tx, light, light.shadow_data, lL, dist, P); + ShadowSample samp = shadow_sample( + is_directional, shadow_atlas_tx, shadow_tilemaps_tx, light, lL, lNg, P); -# ifdef SSS_TRANSMITTANCE - /* Transmittance evaluation first to use initial visibility. */ +#ifdef SSS_TRANSMITTANCE + /* Transmittance evaluation first to use initial visibility without shadow. */ if (diffuse.sss_id != 0u && light.diffuse_power > 0.0) { - float delta = max(thickness, shadow_delta); + float delta = max(thickness, samp.occluder_delta + samp.bias); vec3 intensity = visibility * light.transmit_power * light_translucent(sss_transmittance_tx, @@ -57,11 +59,9 @@ void light_eval_ex(ClosureDiffuse diffuse, delta); out_diffuse += light.color * intensity; } -# endif - - visibility *= float(shadow_delta - light.shadow_data.bias <= 0.0); - } #endif + visibility *= float(samp.occluder_delta + samp.bias >= 0.0); + } if (visibility < 1e-6) { return; @@ -84,6 +84,7 @@ void light_eval_ex(ClosureDiffuse diffuse, void light_eval(ClosureDiffuse diffuse, ClosureReflection reflection, vec3 P, + vec3 Ng, vec3 V, float vP_z, float thickness, @@ -94,12 +95,12 @@ void light_eval(ClosureDiffuse diffuse, uv = uv * UTIL_TEX_UV_SCALE + UTIL_TEX_UV_BIAS; vec4 ltc_mat = utility_tx_sample(utility_tx, uv, UTIL_LTC_MAT_LAYER); - LIGHT_FOREACH_BEGIN_DIRECTIONAL(light_cull_buf, l_idx) - { + LIGHT_FOREACH_BEGIN_DIRECTIONAL (light_cull_buf, l_idx) { light_eval_ex(diffuse, reflection, true, P, + Ng, V, vP_z, thickness, @@ -111,12 +112,12 @@ void light_eval(ClosureDiffuse diffuse, LIGHT_FOREACH_END vec2 px = gl_FragCoord.xy; - LIGHT_FOREACH_BEGIN_LOCAL(light_cull_buf, light_zbin_buf, light_tile_buf, px, vP_z, l_idx) - { + LIGHT_FOREACH_BEGIN_LOCAL (light_cull_buf, light_zbin_buf, light_tile_buf, px, vP_z, l_idx) { light_eval_ex(diffuse, reflection, false, P, + Ng, V, vP_z, thickness, diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl index 144445801cf..761e403b138 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl @@ -9,7 +9,8 @@ void light_vector_get(LightData ld, vec3 P, out vec3 L, out float dist) { - if (ld.type == LIGHT_SUN) { + /* TODO(fclem): Static branching. */ + if (is_sun_light(ld.type)) { L = ld._back; dist = 1.0; } @@ -57,10 +58,13 @@ float light_attenuation(LightData ld, vec3 L, float dist) if (ld.type == LIGHT_SPOT) { vis *= light_spot_attenuation(ld, L); } + if (ld.type >= LIGHT_SPOT) { vis *= step(0.0, -dot(L, -ld._back)); } - if (ld.type != LIGHT_SUN) { + + /* TODO(fclem): Static branching. */ + if (!is_sun_light(ld.type)) { #ifdef VOLUME_LIGHTING vis *= light_influence_attenuation(dist, ld.influence_radius_invsqr_volume); #else diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_ltc_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_ltc_lib.glsl index 57e92b0b9b4..8255b53422e 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_ltc_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_ltc_lib.glsl @@ -45,7 +45,7 @@ vec3 ltc_solve_cubic(vec4 coefs) /* Discriminant */ float discr = dot(vec2(4.0 * delta.x, -delta.y), delta.zy); - /* Clamping avoid NaN output on some platform. (see T67060) */ + /* Clamping avoid NaN output on some platform. (see #67060) */ float sqrt_discr = sqrt(clamp(discr, 0.0, FLT_MAX)); vec2 xlc, xsc; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl new file mode 100644 index 00000000000..bbdcb7334ad --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl @@ -0,0 +1,195 @@ + +/** + * Debug drawing for virtual shadowmaps. + * See eShadowDebug for more information. + */ + +#pragma BLENDER_REQUIRE(common_debug_print_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_light_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +/** Control the scaling of the tilemap splat. */ +const float pixel_scale = 4.0; + +vec3 debug_random_color(ivec2 v) +{ + float r = interlieved_gradient_noise(vec2(v), 0.0, 0.0); + return hue_gradient(r); +} + +vec3 debug_random_color(int v) +{ + return debug_random_color(ivec2(v, 0)); +} + +void debug_tile_print(ShadowTileData tile, ivec4 tile_coord) +{ + drw_print("Tile (", tile_coord.x, ",", tile_coord.y, ") in Tilemap ", tile_coord.z, " : "); + drw_print(tile.lod); + drw_print(tile.page); + drw_print(tile.cache_index); +} + +vec3 debug_tile_state_color(ShadowTileData tile) +{ + if (tile.lod > 0) { + /* Uses data from another LOD. */ + return neon_gradient(float(tile.lod) / float(SHADOW_TILEMAP_LOD)); + } + if (tile.do_update && tile.is_used) { + /* Updated. */ + return vec3(0.5, 1, 0); + } + if (tile.is_used) { + /* Used but was cached. */ + return vec3(0, 1, 0); + } + vec3 col = vec3(0); + if (tile.is_cached) { + col += vec3(0.2, 0, 0.5); + if (tile.do_update) { + col += vec3(0.8, 0, 0); + } + } + return col; +} + +ShadowSample debug_tile_get(vec3 P, LightData light) +{ + vec3 lNg = vec3(1.0, 0.0, 0.0); + if (is_sun_light(light.type)) { + return shadow_directional_sample_get(shadow_atlas_tx, shadow_tilemaps_tx, light, P, lNg); + } + else { + vec3 lL = light_world_to_local(light, P - light._position); + return shadow_punctual_sample_get(shadow_atlas_tx, shadow_tilemaps_tx, light, lL, lNg); + } +} + +LightData debug_light_get() +{ + LIGHT_FOREACH_BEGIN_LOCAL_NO_CULL(light_cull_buf, l_idx) + { + LightData light = light_buf[l_idx]; + if (light.tilemap_index == debug_tilemap_index) { + return light; + } + } + LIGHT_FOREACH_END + + LIGHT_FOREACH_BEGIN_DIRECTIONAL (light_cull_buf, l_idx) { + LightData light = light_buf[l_idx]; + if (light.tilemap_index == debug_tilemap_index) { + return light; + } + } + LIGHT_FOREACH_END +} + +/** Return true if a pixel was written. */ +bool debug_tilemaps(vec3 P, LightData light) +{ + const int debug_tile_size_px = 4; + ivec2 px = ivec2(gl_FragCoord.xy) / debug_tile_size_px; + int tilemap = px.x / SHADOW_TILEMAP_RES; + int tilemap_index = light.tilemap_index + tilemap; + if ((px.y < SHADOW_TILEMAP_RES) && (tilemap_index <= light_tilemap_max_get(light))) { + /* Debug actual values in the tilemap buffer. */ + ShadowTileMapData tilemap = tilemaps_buf[tilemap_index]; + int tile_index = shadow_tile_offset(px % SHADOW_TILEMAP_RES, tilemap.tiles_index, 0); + ShadowTileData tile = shadow_tile_unpack(tiles_buf[tile_index]); + /* Leave 1 px border between tilemaps. */ + if (!any( + equal(ivec2(gl_FragCoord.xy) % (SHADOW_TILEMAP_RES * debug_tile_size_px), ivec2(0)))) { + gl_FragDepth = 0.0; + out_color_add = vec4(debug_tile_state_color(tile), 0.0); + out_color_mul = vec4(0.0); + + if (ivec2(gl_FragCoord.xy) == ivec2(0)) { + drw_print(light.object_mat); + } + return true; + } + } + return false; +} + +void debug_tile_state(vec3 P, LightData light) +{ + ShadowSample samp = debug_tile_get(P, light); + out_color_add = vec4(debug_tile_state_color(samp.tile), 0) * 0.5; + out_color_mul = vec4(0.5); +} + +void debug_atlas_values(vec3 P, LightData light) +{ + ShadowSample samp = debug_tile_get(P, light); + out_color_add = vec4(vec3(samp.occluder_dist), 0); + out_color_mul = vec4(0.0); +} + +void debug_random_tile_color(vec3 P, LightData light) +{ + ShadowSample samp = debug_tile_get(P, light); + out_color_add = vec4(debug_random_color(ivec2(samp.tile.page)), 0) * 0.5; + out_color_mul = vec4(0.5); +} + +void debug_random_tilemap_color(vec3 P, LightData light) +{ + ShadowCoordinates coord; + if (is_sun_light(light.type)) { + vec3 lP = shadow_world_to_local(light, P); + coord = shadow_directional_coordinates(light, lP); + } + else { + vec3 lP = light_world_to_local(light, P - light._position); + int face_id = shadow_punctual_face_index_get(lP); + lP = shadow_punctual_local_position_to_face_local(face_id, lP); + coord = shadow_punctual_coordinates(light, lP, face_id); + } + + out_color_add = vec4(debug_random_color(ivec2(coord.tilemap_index)), 0) * 0.5; + out_color_mul = vec4(0.5); +} + +void main() +{ + /* Default to no output. */ + gl_FragDepth = 1.0; + out_color_add = vec4(0.0); + out_color_mul = vec4(1.0); + + float depth = texelFetch(hiz_tx, ivec2(gl_FragCoord.xy), 0).r; + vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth); + /* Make it pass the depth test. */ + gl_FragDepth = depth - 1e-6; + + LightData light = debug_light_get(); + + if (debug_tilemaps(P, light)) { + return; + } + + if (depth != 1.0) { + switch (eDebugMode(debug_mode)) { + case DEBUG_SHADOW_TILEMAPS: + debug_tile_state(P, light); + break; + case DEBUG_SHADOW_VALUES: + debug_atlas_values(P, light); + break; + case DEBUG_SHADOW_TILE_RANDOM_COLOR: + debug_random_tile_color(P, light); + break; + case DEBUG_SHADOW_TILEMAP_RANDOM_COLOR: + debug_random_tilemap_color(P, light); + break; + } + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_lib.glsl new file mode 100644 index 00000000000..a799ca87501 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_lib.glsl @@ -0,0 +1,222 @@ + +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +/** \a unormalized_uv is the uv coordinates for the whole tilemap [0..SHADOW_TILEMAP_RES]. */ +vec2 shadow_page_uv_transform( + vec2 atlas_size, uvec2 page, uint lod, vec2 unormalized_uv, ivec2 tile_lod0_coord) +{ + /* Bias uv sample for LODs since custom raster aligns LOD pixels instead of centering them. */ + if (lod != 0) { + unormalized_uv += 0.5 / float(SHADOW_PAGE_RES * SHADOW_TILEMAP_RES); + } + float lod_scaling = exp2(-float(lod)); + vec2 target_tile = vec2(tile_lod0_coord >> lod); + vec2 page_uv = unormalized_uv * lod_scaling - target_tile; + /* Assumes atlas is squared. */ + vec2 atlas_uv = (vec2(page) + min(page_uv, 0.99999)) * float(SHADOW_PAGE_RES) / atlas_size; + return atlas_uv; +} + +/* Rotate vector to light's local space . Used for directional shadows. */ +vec3 shadow_world_to_local(LightData ld, vec3 L) +{ + /* Avoid relying on compiler to optimize this. + * vec3 lL = transpose(mat3(ld.object_mat)) * L; */ + vec3 lL; + lL.x = dot(ld.object_mat[0].xyz, L); + lL.y = dot(ld.object_mat[1].xyz, L); + lL.z = dot(ld.object_mat[2].xyz, L); + return lL; +} + +/* TODO(fclem) use utildef version. */ +float shadow_orderedIntBitsToFloat(int int_value) +{ + return intBitsToFloat((int_value < 0) ? (int_value ^ 0x7FFFFFFF) : int_value); +} + +/* ---------------------------------------------------------------------- */ +/** \name Shadow Sampling Functions + * \{ */ + +/* Turns local light coordinate into shadow region index. Matches eCubeFace order. + * \note lL does not need to be normalized. */ +int shadow_punctual_face_index_get(vec3 lL) +{ + vec3 aP = abs(lL); + if (all(greaterThan(aP.xx, aP.yz))) { + return (lL.x > 0.0) ? 1 : 2; + } + else if (all(greaterThan(aP.yy, aP.xz))) { + return (lL.y > 0.0) ? 3 : 4; + } + else { + return (lL.z > 0.0) ? 5 : 0; + } +} + +mat4x4 shadow_load_normal_matrix(LightData light) +{ + if (!is_sun_light(light.type)) { + /* FIXME: Why? */ + float scale = 0.5; + return mat4x4(vec4(scale, 0.0, 0.0, 0.0), + vec4(0.0, scale, 0.0, 0.0), + vec4(0.0, 0.0, 0.0, -1.0), + vec4(0.0, 0.0, light.normal_mat_packed.x, light.normal_mat_packed.y)); + } + else { + float near = shadow_orderedIntBitsToFloat(light.clip_near); + float far = shadow_orderedIntBitsToFloat(light.clip_far); + /* Could be store precomputed inside the light struct. Just have to find a how to update it. */ + float z_scale = (far - near) * 0.5; + return mat4x4(vec4(light.normal_mat_packed.x, 0.0, 0.0, 0.0), + vec4(0.0, light.normal_mat_packed.x, 0.0, 0.0), + vec4(0.0, 0.0, z_scale, 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); + } +} + +/* Returns minimum bias (in world space unit) needed for a given geometry normal and a shadowmap + * page to avoid self shadowing artifacts. Note that this can return a negative bias to better + * match the surface. */ +float shadow_slope_bias_get(vec2 atlas_size, LightData light, vec3 lNg, vec3 lP, vec2 uv, uint lod) +{ + /* Compute coordinate inside the pixel we are sampling. */ + vec2 uv_subpixel_coord = fract(uv * atlas_size); + /* Bias uv sample for LODs since custom raster aligns LOD pixels instead of centering them. */ + uv_subpixel_coord += (lod > 0) ? -exp2(-1.0 - float(lod)) : 0.0; + /* Compute delta to the texel center (where the sample is). */ + vec2 ndc_texel_center_delta = uv_subpixel_coord * 2.0 - 1.0; + /* Create a normal plane equation and go through the normal projection matrix. */ + vec4 lNg_plane = vec4(lNg, -dot(lNg, lP)); + vec4 ndc_Ng = shadow_load_normal_matrix(light) * lNg_plane; + /* Get slope from normal vector. Note that this is signed. */ + vec2 ndc_slope = ndc_Ng.xy / abs(ndc_Ng.z); + /* Clamp out to avoid the bias going to infinity. Remember this is in NDC space. */ + ndc_slope = clamp(ndc_slope, -100.0, 100.0); + /* Compute slope to where the receiver should be by extending the plane to the texel center. */ + float bias = dot(ndc_slope, ndc_texel_center_delta); + /* Bias for 1 pixel of the sampled LOD. */ + bias /= ((SHADOW_TILEMAP_RES * SHADOW_PAGE_RES) >> lod); + return bias; +} + +struct ShadowSample { + /* Signed delta in world units from the shading point to the occluder. Negative if occluded. */ + float occluder_delta; + /* Tile coordinate inside the tilemap [0..SHADOW_TILEMAP_RES). */ + ivec2 tile_coord; + /* UV coordinate inside the tilemap [0..SHADOW_TILEMAP_RES). */ + vec2 uv; + /* Minimum slope bias to apply during comparison. */ + float bias; + /* Distance from near clip plane in world space units. */ + float occluder_dist; + /* Tile used loaded for page indirection. */ + ShadowTileData tile; +}; + +float shadow_tile_depth_get(usampler2D atlas_tx, ShadowTileData tile, vec2 atlas_uv) +{ + if (!tile.is_allocated) { + /* Far plane distance but with a bias to make sure there will be no shadowing. + * But also not FLT_MAX since it can cause issue with projection. */ + return 1.1; + } + return uintBitsToFloat(texture(atlas_tx, atlas_uv).r); +} + +vec2 shadow_punctual_linear_depth(vec2 z, float near, float far) +{ + vec2 d = z * 2.0 - 1.0; + float z_delta = far - near; + /* Can we simplify? */ + return ((-2.0 * near * far) / z_delta) / (d + (-(far + near) / z_delta)); +} + +float shadow_directional_linear_depth(float z, float near, float far) +{ + return z * (near - far) - near; +} + +ShadowSample shadow_punctual_sample_get( + usampler2D atlas_tx, usampler2D tilemaps_tx, LightData light, vec3 lP, vec3 lNg) +{ + int face_id = shadow_punctual_face_index_get(lP); + lNg = shadow_punctual_local_position_to_face_local(face_id, lNg); + lP = shadow_punctual_local_position_to_face_local(face_id, lP); + + ShadowCoordinates coord = shadow_punctual_coordinates(light, lP, face_id); + + vec2 atlas_size = vec2(textureSize(atlas_tx, 0).xy); + + ShadowSample samp; + samp.tile = shadow_tile_load(tilemaps_tx, coord.tile_coord, coord.tilemap_index); + samp.uv = shadow_page_uv_transform( + atlas_size, samp.tile.page, samp.tile.lod, coord.uv, coord.tile_coord); + samp.bias = shadow_slope_bias_get(atlas_size, light, lNg, lP, samp.uv, samp.tile.lod); + + float occluder_ndc = shadow_tile_depth_get(atlas_tx, samp.tile, samp.uv); + /* Depth is cleared to FLT_MAX, clamp it to 1 to avoid issues when converting to linear. */ + occluder_ndc = saturate(occluder_ndc); + + /* NOTE: Given to be both positive, so can use intBitsToFloat instead of orderedInt version. */ + float near = intBitsToFloat(light.clip_near); + float far = intBitsToFloat(light.clip_far); + /* Shadow is stored as gl_FragCoord.z. Convert to radial distance along with the bias. */ + vec2 occluder = vec2(occluder_ndc, saturate(occluder_ndc + samp.bias)); + vec2 occluder_z = shadow_punctual_linear_depth(occluder, near, far); + float receiver_dist = length(lP); + float radius_divisor = receiver_dist / abs(lP.z); + samp.occluder_dist = occluder_z.x * radius_divisor; + samp.bias = (occluder_z.y - occluder_z.x) * radius_divisor; + samp.occluder_delta = samp.occluder_dist - receiver_dist; + return samp; +} + +ShadowSample shadow_directional_sample_get( + usampler2D atlas_tx, usampler2D tilemaps_tx, LightData light, vec3 P, vec3 lNg) +{ + vec3 lP = shadow_world_to_local(light, P); + ShadowCoordinates coord = shadow_directional_coordinates(light, lP); + + vec2 atlas_size = vec2(textureSize(atlas_tx, 0).xy); + + ShadowSample samp; + samp.tile = shadow_tile_load(tilemaps_tx, coord.tile_coord, coord.tilemap_index); + samp.uv = shadow_page_uv_transform( + atlas_size, samp.tile.page, samp.tile.lod, coord.uv, coord.tile_coord); + samp.bias = shadow_slope_bias_get(atlas_size, light, lNg, lP, samp.uv, samp.tile.lod); + samp.bias *= exp2(float(coord.lod_relative)); + + float occluder_ndc = shadow_tile_depth_get(atlas_tx, samp.tile, samp.uv); + + float near = shadow_orderedIntBitsToFloat(light.clip_near); + float far = shadow_orderedIntBitsToFloat(light.clip_far); + samp.occluder_dist = shadow_directional_linear_depth(occluder_ndc, near, far); + /* Receiver distance needs to also be increasing. + * Negate since Z distance follows blender camera convention of -Z as forward. */ + float receiver_dist = -lP.z; + samp.bias *= near - far; + samp.occluder_delta = samp.occluder_dist - receiver_dist; + return samp; +} + +ShadowSample shadow_sample(const bool is_directional, + usampler2D atlas_tx, + usampler2D tilemaps_tx, + LightData light, + vec3 lL, + vec3 lNg, + vec3 P) +{ + if (is_directional) { + return shadow_directional_sample_get(atlas_tx, tilemaps_tx, light, P, lNg); + } + else { + return shadow_punctual_sample_get(atlas_tx, tilemaps_tx, light, lL, lNg); + } +} + +/** \} */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_allocate_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_allocate_comp.glsl new file mode 100644 index 00000000000..786b2376595 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_allocate_comp.glsl @@ -0,0 +1,41 @@ + +/** + * Virtual shadowmapping: Allocation. + * + * Allocates pages to tiles needing them. + * Note that allocation can fail, in this case the tile is left with no page. + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_page_ops_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +void main() +{ + ShadowTileMapData tilemap_data = tilemaps_buf[gl_GlobalInvocationID.z]; + + int tile_start = tilemap_data.tiles_index; + for (int lod = 0; lod <= SHADOW_TILEMAP_LOD; lod++) { + int lod_len = SHADOW_TILEMAP_LOD0_LEN >> (lod * 2); + int local_tile = int(gl_LocalInvocationID.x); + if (local_tile < lod_len) { + int tile_index = tile_start + local_tile; + + ShadowTileData tile = shadow_tile_unpack(tiles_buf[tile_index]); + if (tile.is_used && !tile.is_allocated) { + shadow_page_alloc(tile); + tiles_buf[tile_index] = shadow_tile_pack(tile); + } + + if (tile.is_used) { + atomicAdd(statistics_buf.page_used_count, 1); + } + if (tile.is_used && tile.do_update) { + atomicAdd(statistics_buf.page_update_count, 1); + } + if (tile.is_allocated) { + atomicAdd(statistics_buf.page_allocated_count, 1); + } + } + tile_start += lod_len; + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_clear_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_clear_comp.glsl new file mode 100644 index 00000000000..029d584cdad --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_clear_comp.glsl @@ -0,0 +1,17 @@ + +/** + * Virtual shadowmapping: Page Clear. + * + * Equivalent to a framebuffer depth clear but only for pages pushed to the clear_page_buf. + */ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + +void main() +{ + uvec2 page_co = unpackUvec2x16(clear_page_buf[gl_GlobalInvocationID.z]); + uvec2 page_texel = page_co * pages_infos_buf.page_size + gl_GlobalInvocationID.xy; + + /* Clear to FLT_MAX instead of 1 so the far plane doesn't cast shadows onto farther objects. */ + imageStore(atlas_img, ivec2(page_texel), uvec4(floatBitsToUint(FLT_MAX))); +} diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl new file mode 100644 index 00000000000..57de4ed4e2e --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl @@ -0,0 +1,129 @@ + +/** + * Virtual shadowmapping: Defrag. + * + * Defragment the cached page buffer making one continuous array. + * + * Also pop_front the cached pages if there is not enough free pages for the needed allocations. + * Here is an example of the behavior of this buffer during one update cycle: + * + * Initial state: 5 cached pages. Buffer starts at index 2 and ends at 6. + * [--xxxxx---------] + * After page free step: 2 cached pages were removed (r), 3 pages were inserted in the cache (i). + * [--xrxrxiii------] + * After page defrag step: The buffer is compressed into only 6 pages. + * [----xxxxxx------] + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_page_ops_lib.glsl) + +const uint max_page = SHADOW_MAX_PAGE; + +void find_first_valid(inout uint src, uint dst) +{ + for (; src < dst; src++) { + if (pages_cached_buf[src % max_page].x != uint(-1)) { + return; + } + } +} + +void page_cached_free(uint page_index) +{ + uint tile_index = pages_cached_buf[page_index].y; + ShadowTileData tile = shadow_tile_unpack(tiles_buf[tile_index]); + + shadow_page_cache_remove(tile); + shadow_page_free(tile); + + tiles_buf[tile_index] = shadow_tile_pack(tile); +} + +#if 0 /* Can be used to debug heap and invalid pages inside the free buffer. */ +# define check_heap_integrity(heap, start, size, invalid_val, result) \ + result = true; \ + for (int i = 0; i < max_page; i++) { \ + if ((i >= start) && (i < (start + size))) { \ + result = result && (heap[i].x != invalid_val); \ + } \ + else { \ + result = result && (heap[i].x == invalid_val); \ + } \ + } +#else +# define check_heap_integrity(heap, start, size, invalid_val, result) +#endif + +void main() +{ + /* Pages we need to get off the cache for the allocation pass. */ + int additional_pages = pages_infos_buf.page_alloc_count - pages_infos_buf.page_free_count; + + uint src = pages_infos_buf.page_cached_start; + uint end = pages_infos_buf.page_cached_end; + + find_first_valid(src, end); + + bool valid_pre; + check_heap_integrity(pages_free_buf, 0, pages_infos_buf.page_free_count, uint(-1), valid_pre); + + /* First free as much pages as needed from the end of the cached range to fulfill the allocation. + * Avoid defragmenting to then free them. */ + for (; additional_pages > 0 && src < end; additional_pages--) { + page_cached_free(src % max_page); + find_first_valid(src, end); + } + + /* Defrag page in "old" range. */ + bool is_empty = (src == end); + if (!is_empty) { + /* `page_cached_end` refers to the next empty slot. + * Decrement by one to refer to the first slot we can defrag. */ + for (uint dst = end - 1; dst > src; dst--) { + /* Find hole. */ + if (pages_cached_buf[dst % max_page].x != uint(-1)) { + continue; + } + /* Update corresponding reference in tile. */ + shadow_page_cache_update_page_ref(src % max_page, dst % max_page); + /* Move page. */ + pages_cached_buf[dst % max_page] = pages_cached_buf[src % max_page]; + pages_cached_buf[src % max_page] = uvec2(-1); + + find_first_valid(src, dst); + } + } + + end = pages_infos_buf.page_cached_next; + /* Free pages in the "new" range (these are compact). */ + for (; additional_pages > 0 && src < end; additional_pages--, src++) { + page_cached_free(src % max_page); + } + + bool valid_post; + check_heap_integrity(pages_free_buf, 0, pages_infos_buf.page_free_count, uint(-1), valid_post); + + pages_infos_buf.page_cached_start = src; + pages_infos_buf.page_cached_end = end; + pages_infos_buf.page_alloc_count = 0; + pages_infos_buf.view_count = 0; + + /* Stats. */ + statistics_buf.page_used_count = 0; + statistics_buf.page_update_count = 0; + statistics_buf.page_allocated_count = 0; + statistics_buf.page_rendered_count = 0; + + /* Wrap the cursor to avoid unsigned overflow. We do not do modulo arithmetic because it would + * produce a 0 length buffer if the buffer is full. */ + if (pages_infos_buf.page_cached_start > max_page) { + pages_infos_buf.page_cached_next -= max_page; + pages_infos_buf.page_cached_start -= max_page; + pages_infos_buf.page_cached_end -= max_page; + } + + /* Reset clear command indirect buffer. */ + clear_dispatch_buf.num_groups_x = pages_infos_buf.page_size / SHADOW_PAGE_CLEAR_GROUP_SIZE; + clear_dispatch_buf.num_groups_y = pages_infos_buf.page_size / SHADOW_PAGE_CLEAR_GROUP_SIZE; + clear_dispatch_buf.num_groups_z = 0; +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_free_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_free_comp.glsl new file mode 100644 index 00000000000..8332da2f273 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_free_comp.glsl @@ -0,0 +1,54 @@ + +/** + * Virtual shadowmapping: Tile page freeing. + * + * Releases the allocated pages held by tilemaps that have been become unused. + * Also reclaim cached pages if the tiles needs them. + * Note that we also count the number of new page allocations needed. + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_page_ops_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +void main() +{ + ShadowTileMapData tilemap_data = tilemaps_buf[gl_GlobalInvocationID.z]; + + int tile_start = tilemap_data.tiles_index; + for (int lod = 0; lod <= SHADOW_TILEMAP_LOD; lod++) { + int lod_len = SHADOW_TILEMAP_LOD0_LEN >> (lod * 2); + int local_tile = int(gl_LocalInvocationID.x); + if (local_tile < lod_len) { + int tile_index = tile_start + local_tile; + + ShadowTileData tile = shadow_tile_unpack(tiles_buf[tile_index]); + + bool is_orphaned = !tile.is_used && tile.do_update; + if (is_orphaned) { + if (tile.is_cached) { + shadow_page_cache_remove(tile); + } + if (tile.is_allocated) { + shadow_page_free(tile); + } + } + + if (tile.is_used) { + if (tile.is_cached) { + shadow_page_cache_remove(tile); + } + if (!tile.is_allocated) { + atomicAdd(pages_infos_buf.page_alloc_count, 1); + } + } + else { + if (tile.is_allocated) { + shadow_page_cache_append(tile, tile_index); + } + } + + tiles_buf[tile_index] = shadow_tile_pack(tile); + } + tile_start += lod_len; + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_mask_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_mask_comp.glsl new file mode 100644 index 00000000000..3ac32a8bb8b --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_mask_comp.glsl @@ -0,0 +1,55 @@ + +/** + * Virtual shadowmapping: Usage un-tagging + * + * Remove used tag from masked tiles (LOD overlap). + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +shared uint usage_grid[SHADOW_TILEMAP_RES / 2][SHADOW_TILEMAP_RES / 2]; + +void main() +{ + uint tilemap_index = gl_GlobalInvocationID.z; + ShadowTileMapData tilemap = tilemaps_buf[tilemap_index]; + + if (tilemap.projection_type == SHADOW_PROJECTION_CUBEFACE) { + /* For each level collect the number of used (or masked) tile that are covering the tile from + * the level underneath. If this adds up to 4 the underneath tile is flag unused as its data + * is not needed for rendering. + * + * This is because 2 receivers can tag used the same area of the shadowmap but with different + * LODs. */ + bool is_used = false; + ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy); + uint lod_size = uint(SHADOW_TILEMAP_RES); + for (int lod = 0; lod <= SHADOW_TILEMAP_LOD; lod++, lod_size >>= 1u) { + bool thread_active = all(lessThan(tile_co, ivec2(lod_size))); + + barrier(); + + ShadowTileData tile; + if (thread_active) { + int tile_offset = shadow_tile_offset(tile_co, tilemap.tiles_index, lod); + tile = shadow_tile_unpack(tiles_buf[tile_offset]); + if (lod > 0 && usage_grid[tile_co.y][tile_co.x] == 4u) { + /* Remove the usage flag as this tile is completely covered by higher LOD tiles. */ + tiles_buf[tile_offset] &= ~SHADOW_IS_USED; + /* Consider this tile occluding lower levels. */ + tile.is_used = true; + } + /* Reset count for next level. */ + usage_grid[tile_co.y][tile_co.x] = 0u; + } + + barrier(); + + if (thread_active) { + if (tile.is_used) { + atomicAdd(usage_grid[tile_co.y / 2][tile_co.x / 2], 1u); + } + } + } + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_ops_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_ops_lib.glsl new file mode 100644 index 00000000000..062040ab008 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_ops_lib.glsl @@ -0,0 +1,108 @@ + +/** + * Operations to move virtual shadow map pages between heaps and tiles. + * We reuse the blender::vector class denomination. + * + * The needed resources for this lib are: + * - tiles_buf + * - pages_free_buf + * - pages_cached_buf + * - pages_infos_buf + * + * A page is can be in 3 state (free, cached, acquired). Each one correspond to a different owner. + * + * - The pages_free_buf works in a regular stack containing only the page coordinates. + * + * - The pages_cached_buf is a ring buffer where newly cached pages gets added at the end and the + * old cached pages gets defragmented at the start of the used portion. + * + * - The tiles_buf only owns a page if it is used. If the page is cached, the tile contains a + * reference index inside the pages_cached_buf. + * + * IMPORTANT: Do not forget to manually store the tile data after doing operations on them. + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +/* TODO(@fclem): Implement. */ +#define assert(check) + +/* Remove page ownership from the tile and append it to the cache. */ +void shadow_page_free(inout ShadowTileData tile) +{ + assert(tile.is_allocated); + + int index = atomicAdd(pages_infos_buf.page_free_count, 1); + assert(index < SHADOW_MAX_PAGE); + /* Insert in heap. */ + pages_free_buf[index] = packUvec2x16(tile.page); + /* Remove from tile. */ + tile.page = uvec2(-1); + tile.is_cached = false; + tile.is_allocated = false; +} + +/* Remove last page from the free heap and give ownership to the tile. */ +void shadow_page_alloc(inout ShadowTileData tile) +{ + assert(!tile.is_allocated); + + int index = atomicAdd(pages_infos_buf.page_free_count, -1) - 1; + /* This can easily happen in really big scene. */ + if (index < 0) { + return; + } + /* Insert in tile. */ + tile.page = unpackUvec2x16(pages_free_buf[index]); + tile.is_allocated = true; + tile.do_update = true; + /* Remove from heap. */ + pages_free_buf[index] = uint(-1); +} + +/* Remove page ownership from the tile cache and append it to the cache. */ +void shadow_page_cache_append(inout ShadowTileData tile, uint tile_index) +{ + assert(tile.is_allocated); + + /* The page_cached_next is also wrapped in the defrag phase to avoid unsigned overflow. */ + uint index = atomicAdd(pages_infos_buf.page_cached_next, 1u) % uint(SHADOW_MAX_PAGE); + /* Insert in heap. */ + pages_cached_buf[index] = uvec2(packUvec2x16(tile.page), tile_index); + /* Remove from tile. */ + tile.page = uvec2(-1); + tile.cache_index = index; + tile.is_cached = true; + tile.is_allocated = false; +} + +/* Remove page from cache and give ownership to the tile. */ +void shadow_page_cache_remove(inout ShadowTileData tile) +{ + assert(!tile.is_allocated); + assert(tile.is_cached); + + uint index = tile.cache_index; + /* Insert in tile. */ + tile.page = unpackUvec2x16(pages_cached_buf[index].x); + tile.cache_index = uint(-1); + tile.is_cached = false; + tile.is_allocated = true; + /* Remove from heap. Leaves hole in the buffer. This is handled by the defrag phase. */ + pages_cached_buf[index] = uvec2(-1); +} + +/* Update cached page reference when a cached page moves inside the cached page buffer. */ +void shadow_page_cache_update_page_ref(uint page_index, uint new_page_index) +{ + uint tile_index = pages_cached_buf[page_index].y; + ShadowTileData tile = shadow_tile_unpack(tiles_buf[tile_index]); + tile.cache_index = new_page_index; + tiles_buf[tile_index] = shadow_tile_pack(tile); +} + +/* Update cached page reference when a tile referencing a cached page moves inside the tilemap. */ +void shadow_page_cache_update_tile_ref(uint page_index, uint new_tile_index) +{ + pages_cached_buf[page_index].y = new_tile_index; +} diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_update_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_update_comp.glsl new file mode 100644 index 00000000000..9e31172fd05 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_update_comp.glsl @@ -0,0 +1,94 @@ + +/** + * Virtual shadowmapping: Update tagging + * + * Any updated shadow caster needs to tag the shadow map tiles it was in and is now into. + * This is done in 2 pass of this same shader. One for past object bounds and one for new object + * bounds. The bounding boxes are roughly software rasterized (just a plain rect) in order to tag + * the appropriate tiles. + */ + +#pragma BLENDER_REQUIRE(common_intersect_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_aabb_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +vec3 safe_project(mat4 winmat, mat4 viewmat, inout int clipped, vec3 v) +{ + vec4 tmp = winmat * (viewmat * vec4(v, 1.0)); + /* Detect case when point is behind the camera. */ + clipped += int(tmp.w < 0.0); + return tmp.xyz / tmp.w; +} + +void main() +{ + ShadowTileMapData tilemap = tilemaps_buf[gl_GlobalInvocationID.z]; + + IsectPyramid frustum; + if (tilemap.projection_type == SHADOW_PROJECTION_CUBEFACE) { + Pyramid pyramid = shadow_tilemap_cubeface_bounds(tilemap, ivec2(0), ivec2(SHADOW_TILEMAP_RES)); + frustum = isect_data_setup(pyramid); + } + + uint resource_id = resource_ids_buf[gl_GlobalInvocationID.x]; + + IsectBox box = isect_data_setup(bounds_buf[resource_id].bounding_corners[0].xyz, + bounds_buf[resource_id].bounding_corners[1].xyz, + bounds_buf[resource_id].bounding_corners[2].xyz, + bounds_buf[resource_id].bounding_corners[3].xyz); + + int clipped = 0; + /* NDC space post projection [-1..1] (unclamped). */ + AABB aabb_ndc = aabb_init_min_max(); + for (int v = 0; v < 8; v++) { + aabb_merge(aabb_ndc, safe_project(tilemap.winmat, tilemap.viewmat, clipped, box.corners[v])); + } + + if (tilemap.projection_type == SHADOW_PROJECTION_CUBEFACE) { + if (clipped == 8) { + /* All verts are behind the camera. */ + return; + } + else if (clipped > 0) { + /* Not all verts are behind the near clip plane. */ + if (intersect(frustum, box)) { + /* We cannot correctly handle this case so we fallback by covering the whole view. */ + aabb_ndc.max = vec3(1.0); + aabb_ndc.min = vec3(-1.0); + } + else { + /* Still out of the frustum. Ignore. */ + return; + } + } + } + + AABB aabb_tag; + AABB aabb_map = AABB(vec3(-0.99999), vec3(0.99999)); + + /* Directionnal winmat have no correct near/far in the Z dimension at this point. + * Do not clip in this dimension. */ + if (tilemap.projection_type != SHADOW_PROJECTION_CUBEFACE) { + aabb_map.min.z = -FLT_MAX; + aabb_map.max.z = FLT_MAX; + } + + if (!aabb_clip(aabb_map, aabb_ndc, aabb_tag)) { + return; + } + + /* Raster the bounding rectangle of the Box projection. */ + const float tilemap_half_res = float(SHADOW_TILEMAP_RES / 2); + ivec2 box_min = ivec2(aabb_tag.min.xy * tilemap_half_res + tilemap_half_res); + ivec2 box_max = ivec2(aabb_tag.max.xy * tilemap_half_res + tilemap_half_res); + + for (int lod = 0; lod <= SHADOW_TILEMAP_LOD; lod++, box_min >>= 1, box_max >>= 1) { + for (int y = box_min.y; y <= box_max.y; y++) { + for (int x = box_min.x; x <= box_max.x; x++) { + int tile_index = shadow_tile_offset(ivec2(x, y), tilemap.tiles_index, lod); + atomicOr(tiles_buf[tile_index], SHADOW_DO_UPDATE); + } + } + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_comp.glsl new file mode 100644 index 00000000000..5df9bc80ef5 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_comp.glsl @@ -0,0 +1,32 @@ + +/** + * Virtual shadowmapping: Usage tagging + * + * Shadow pages are only allocated if they are visible. + * This pass scan the depth buffer and tag all tiles that are needed for light shadowing as + * needed. + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_tag_usage_lib.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + ivec2 tex_size = textureSize(depth_tx, 0).xy; + + if (!in_range_inclusive(texel, ivec2(0), ivec2(tex_size - 1))) { + return; + } + + float depth = texelFetch(depth_tx, texel, 0).r; + if (depth == 1.0) { + return; + } + + vec2 uv = vec2(texel) / vec2(tex_size); + vec3 vP = get_view_space_from_depth(uv, depth); + vec3 P = transform_point(ViewMatrixInverse, vP); + vec2 pixel = vec2(gl_GlobalInvocationID.xy); + + shadow_tag_usage(vP, P, pixel); +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_frag.glsl new file mode 100644 index 00000000000..378fb870253 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_frag.glsl @@ -0,0 +1,15 @@ + +/** + * Virtual shadowmapping: Usage tagging + * + * Shadow pages are only allocated if they are visible. + * This pass scan the depth buffer and tag all tiles that are needed for light shadowing as + * needed. + */ + +#pragma BLENDER_REQUIRE(eevee_shadow_tag_usage_lib.glsl) + +void main() +{ + shadow_tag_usage(interp.vP, interp.P, gl_FragCoord.xy); +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_lib.glsl new file mode 100644 index 00000000000..ad305d86744 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_lib.glsl @@ -0,0 +1,104 @@ + +/** + * Virtual shadowmapping: Usage tagging + * + * Shadow pages are only allocated if they are visible. + * This pass scan the depth buffer and tag all tiles that are needed for light shadowing as + * needed. + */ + +#pragma BLENDER_REQUIRE(common_intersect_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_light_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_lib.glsl) + +void shadow_tag_usage_tilemap(uint l_idx, vec3 P, float dist_to_cam, const bool is_directional) +{ + LightData light = light_buf[l_idx]; + + if (light.tilemap_index == LIGHT_NO_SHADOW) { + return; + } + + int lod = 0; + ivec2 tile_co; + int tilemap_index = light.tilemap_index; + if (is_directional) { + vec3 lP = shadow_world_to_local(light, P); + + ShadowCoordinates coord = shadow_directional_coordinates(light, lP); + + tile_co = coord.tile_coord; + tilemap_index = coord.tilemap_index; + } + else { + vec3 lP = light_world_to_local(light, P - light._position); + float dist_to_light = length(lP); + if (dist_to_light > light.influence_radius_max) { + return; + } + if (light.type == LIGHT_SPOT) { + /* Early out if out of cone. */ + float angle_tan = length(lP.xy / dist_to_light); + if (angle_tan > light.spot_tan) { + return; + } + } + else if (is_area_light(light.type)) { + /* Early out if on the wrong side. */ + if (lP.z > 0.0) { + return; + } + } + + /* How much a shadow map pixel covers a final image pixel. + * We project a shadow map pixel (as a sphere for simplicity) to the receiver plane. + * We then reproject this sphere onto the camera screen and compare it to the film pixel size. + * This gives a good approximation of what LOD to select to get a somewhat uniform shadow map + * resolution in screen space. */ + float footprint_ratio = dist_to_light; + /* Project the radius to the screen. 1 unit away from the camera the same way + * pixel_world_radius_inv was computed. Not needed in orthographic mode. */ + bool is_persp = (ProjectionMatrix[3][3] == 0.0); + if (is_persp) { + footprint_ratio /= dist_to_cam; + } + /* Apply resolution ratio. */ + footprint_ratio *= tilemap_projection_ratio; + + int face_id = shadow_punctual_face_index_get(lP); + lP = shadow_punctual_local_position_to_face_local(face_id, lP); + + ShadowCoordinates coord = shadow_punctual_coordinates(light, lP, face_id); + tile_co = coord.tile_coord; + tilemap_index = coord.tilemap_index; + + lod = int(ceil(-log2(footprint_ratio) + tilemaps_buf[tilemap_index].lod_bias)); + lod = clamp(lod, 0, SHADOW_TILEMAP_LOD); + } + tile_co >>= lod; + + if (tilemap_index > light_tilemap_max_get(light)) { + return; + } + + int tile_index = shadow_tile_offset(tile_co, tilemaps_buf[tilemap_index].tiles_index, lod); + atomicOr(tiles_buf[tile_index], SHADOW_IS_USED); +} + +void shadow_tag_usage(vec3 vP, vec3 P, vec2 pixel) +{ + float dist_to_cam = length(vP); + + LIGHT_FOREACH_BEGIN_DIRECTIONAL (light_cull_buf, l_idx) { + shadow_tag_usage_tilemap(l_idx, P, dist_to_cam, true); + } + LIGHT_FOREACH_END + + LIGHT_FOREACH_BEGIN_LOCAL (light_cull_buf, light_zbin_buf, light_tile_buf, pixel, vP.z, l_idx) { + shadow_tag_usage_tilemap(l_idx, P, dist_to_cam, false); + } + LIGHT_FOREACH_END +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_vert.glsl new file mode 100644 index 00000000000..130ce6512b2 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tag_usage_vert.glsl @@ -0,0 +1,22 @@ + +/** + * Virtual shadowmapping: Usage tagging + * + * Shadow pages are only allocated if they are visible. + * This renders bounding boxes for transparent objects in order to tag the correct shadows. + */ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +void main() +{ + ObjectBounds bounds = bounds_buf[drw_ResourceID]; + + interp.P = bounds.bounding_corners[0].xyz; + interp.P += bounds.bounding_corners[1].xyz * pos.x; + interp.P += bounds.bounding_corners[2].xyz * pos.y; + interp.P += bounds.bounding_corners[3].xyz * pos.z; + interp.vP = point_world_to_view(interp.P); + + gl_Position = point_world_to_ndc(interp.P); +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_test.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_test.glsl new file mode 100644 index 00000000000..d7d712ae3cb --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_test.glsl @@ -0,0 +1,398 @@ +/* Directive for resetting the line numbering so the failing tests lines can be printed. + * This conflict with the shader compiler error logging scheme. + * Comment out for correct compilation error line. */ +#line 5 + +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_test_lib.glsl) + +#define TEST(a, b) if (true) + +void main() +{ + TEST(eevee_shadow, DirectionalClipmapLevel) + { + LightData light; + light.type = LIGHT_SUN; + light.clipmap_lod_min = -5; + light.clipmap_lod_max = 8; + light._clipmap_lod_bias = 0.0; + float fac = float(SHADOW_TILEMAP_RES - 1) / float(SHADOW_TILEMAP_RES); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 0.0)), light.clipmap_lod_min); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 0.49)), 1); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 0.5)), 1); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 0.51)), 1); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 0.99)), 2); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 1.0)), 2); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 1.01)), 2); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 12.5)), 6); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 12.51)), 6); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 15.9999)), 6); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 16.0)), 6); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 16.00001)), 6); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 5000.0)), light.clipmap_lod_max); + /* Produces NaN / Inf, Undefined behavior. */ + // EXPECT_EQ(shadow_directional_level(light, vec3(FLT_MAX)), light.clipmap_lod_max); + } + + TEST(eevee_shadow, DirectionalCascadeLevel) + { + LightData light; + light.type = LIGHT_SUN_ORTHO; + light.clipmap_lod_min = 2; + light.clipmap_lod_max = 8; + float half_size = exp2(float(light.clipmap_lod_min - 1)); + light._clipmap_lod_bias = light.clipmap_lod_min - 1; + float fac = float(SHADOW_TILEMAP_RES - 1) / float(SHADOW_TILEMAP_RES); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * half_size * 0.0, 0.0, 0.0)), 2); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * half_size * 0.5, 0.0, 0.0)), 2); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * half_size * 1.0, 0.0, 0.0)), 3); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * half_size * 1.5, 0.0, 0.0)), 3); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * half_size * 2.0, 0.0, 0.0)), 4); + EXPECT_EQ(shadow_directional_level(light, vec3(fac * 5000.0)), light.clipmap_lod_max); + /* Produces NaN / Inf, Undefined behavior. */ + // EXPECT_EQ(shadow_directional_level(light, vec3(FLT_MAX)), light.clipmap_lod_max); + } + + TEST(eevee_shadow, DirectionalClipmapCoordinates) + { + ShadowCoordinates coords; + vec3 lP, camera_lP; + + LightData light; + light.type = LIGHT_SUN; + light.clipmap_lod_min = 0; /* Range [-0.5..0.5]. */ + light.clipmap_lod_max = 2; /* Range [-2..2]. */ + light.tilemap_index = light.clipmap_lod_min; + light._position = vec3(0.0); + float lod_min_tile_size = exp2(float(light.clipmap_lod_min)) / float(SHADOW_TILEMAP_RES); + float lod_max_half_size = exp2(float(light.clipmap_lod_max)) / 2.0; + + camera_lP = vec3(0.0, 0.0, 0.0); + /* Follows ShadowDirectional::end_sync(). */ + light.clipmap_base_offset = ivec2(round(camera_lP.xy / lod_min_tile_size)); + EXPECT_EQ(light.clipmap_base_offset, ivec2(0)); + + /* Test UVs and tile mapping. */ + + lP = vec3(1e-5, 1e-5, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 0); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 2), 1e-3); + + lP = vec3(-1e-5, -1e-5, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 0); + EXPECT_EQ(coords.tile_coord, ivec2((SHADOW_TILEMAP_RES / 2) - 1)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 2), 1e-3); + + lP = vec3(-0.5, -0.5, 0.0); /* Min of first LOD. */ + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 0); + EXPECT_EQ(coords.tile_coord, ivec2(0)); + EXPECT_NEAR(coords.uv, vec2(0), 1e-3); + + lP = vec3(0.5, 0.5, 0.0); /* Max of first LOD. */ + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 0); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES - 1)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES), 1e-3); + + /* Test clipmap level selection. */ + + camera_lP = vec3(2.0, 2.0, 0.0); + /* Follows ShadowDirectional::end_sync(). */ + light.clipmap_base_offset = ivec2(round(camera_lP.xy / lod_min_tile_size)); + EXPECT_EQ(light.clipmap_base_offset, ivec2(32)); + + lP = vec3(2.00001, 2.00001, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 0); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 2), 1e-3); + + lP = vec3(1.50001, 1.50001, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 1); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 4)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 4), 1e-3); + + lP = vec3(1.00001, 1.00001, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 2); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 4)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 4), 1e-3); + + lP = vec3(-0.0001, -0.0001, 0.0); /* Out of bounds. */ + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 2); + EXPECT_EQ(coords.tile_coord, ivec2(0)); + EXPECT_NEAR(coords.uv, vec2(0), 1e-3); + + /* Test clipmap offset. */ + + light.clipmap_base_offset = ivec2(31, 1); + lP = vec3(2.0001, 0.0001, 0.0); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, -1)); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, 0)); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, 0)); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, 0)); + + /* Test clipmap negative offsets. */ + + light.clipmap_base_offset = ivec2(-31, -1); + lP = vec3(-2.0001, -0.0001, 0.0); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 1)); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 0)); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 0)); + + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 0)); + } + TEST(eevee_shadow, DirectionalCascadeCoordinates) + { + ShadowCoordinates coords; + vec3 lP, camera_lP; + + LightData light; + light.type = LIGHT_SUN_ORTHO; + light.clipmap_lod_min = 0; /* Range [-0.5..0.5]. */ + light.clipmap_lod_max = 2; /* 3 tilemaps. */ + light.tilemap_index = 1; + light._position = vec3(0.0); + light._clipmap_lod_bias = light.clipmap_lod_min - 1; + light._clipmap_origin_x = 0.0; + light._clipmap_origin_y = 0.0; + float lod_tile_size = exp2(float(light.clipmap_lod_min)) / float(SHADOW_TILEMAP_RES); + float lod_half_size = exp2(float(light.clipmap_lod_min)) / 2.0; + float narrowing = float(SHADOW_TILEMAP_RES - 1) / float(SHADOW_TILEMAP_RES); + + camera_lP = vec3(0.0, 0.0, 0.0); + int level_range_size = light.clipmap_lod_max - light.clipmap_lod_min + 1; + vec2 farthest_tilemap_center = vec2(lod_half_size * float(level_range_size - 1), 0.0); + light.clipmap_base_offset = floatBitsToInt( + vec2(lod_half_size / float(level_range_size - 1), 0.0)); + + /* Test UVs and tile mapping. */ + + lP = vec3(1e-8, 1e-8, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 1); + EXPECT_EQ(coords.lod_relative, 0); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 2), 1e-3); + + lP = vec3(lod_half_size * narrowing - 1e-5, 1e-8, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 1); + EXPECT_EQ(coords.lod_relative, 0); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES - 1, SHADOW_TILEMAP_RES / 2)); + EXPECT_NEAR(coords.uv, vec2(float(SHADOW_TILEMAP_RES) - 0.5, SHADOW_TILEMAP_RES / 2), 1e-3); + + lP = vec3(lod_half_size + 1e-5, 1e-5, 0.0); + coords = shadow_directional_coordinates(light, lP); + EXPECT_EQ(coords.tilemap_index, 2); + EXPECT_EQ(coords.lod_relative, 0); + EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES - 1, SHADOW_TILEMAP_RES / 2)); + EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES, SHADOW_TILEMAP_RES / 2), 1e-3); + + // lP = vec3(-0.5, -0.5, 0.0); /* Min of first LOD. */ + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tilemap_index, 0); + // EXPECT_EQ(coords.tile_coord, ivec2(0)); + // EXPECT_NEAR(coords.uv, vec2(0), 1e-3); + + // lP = vec3(0.5, 0.5, 0.0); /* Max of first LOD. */ + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tilemap_index, 0); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES - 1)); + // EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES), 1e-3); + + /* Test clipmap level selection. */ + + // camera_lP = vec3(2.0, 2.0, 0.0); + /* Follows ShadowDirectional::end_sync(). */ + // light.clipmap_base_offset = ivec2(round(camera_lP.xy / lod_min_tile_size)); + // EXPECT_EQ(light.clipmap_base_offset, ivec2(32)); + + // lP = vec3(2.00001, 2.00001, 0.0); + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tilemap_index, 0); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2)); + // EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 2), 1e-3); + + // lP = vec3(1.50001, 1.50001, 0.0); + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tilemap_index, 1); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 4)); + // EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 4), 1e-3); + + // lP = vec3(1.00001, 1.00001, 0.0); + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tilemap_index, 2); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 4)); + // EXPECT_NEAR(coords.uv, vec2(SHADOW_TILEMAP_RES / 4), 1e-3); + + // lP = vec3(-0.0001, -0.0001, 0.0); /* Out of bounds. */ + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tilemap_index, 2); + // EXPECT_EQ(coords.tile_coord, ivec2(0)); + // EXPECT_NEAR(coords.uv, vec2(0), 1e-3); + + /* Test clipmap offset. */ + + // light.clipmap_base_offset = ivec2(31, 1); + // lP = vec3(2.0001, 0.0001, 0.0); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, -1)); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, 0)); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, 0)); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2) + ivec2(1, 0)); + + /* Test clipmap negative offsets. */ + + // light.clipmap_base_offset = ivec2(-31, -1); + // lP = vec3(-2.0001, -0.0001, 0.0); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 1)); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 0)); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 0)); + + // coords = shadow_directional_coordinates(light, lP); + // EXPECT_EQ(coords.tile_coord, ivec2(SHADOW_TILEMAP_RES / 2 - 1) + ivec2(-1, 0)); + } + + TEST(eevee_shadow, DirectionalSlopeBias) + { + float near = 0.0, far = 1.0; + LightData light; + light.type = LIGHT_SUN; + light.clip_near = floatBitsToInt(near); + light.clip_far = floatBitsToInt(far); + light.clipmap_lod_min = 0; + + /* Position has no effect for directionnal. */ + vec3 lP = vec3(0.0); + vec2 atlas_size = vec2(SHADOW_TILEMAP_RES); + { + vec3 lNg = vec3(0.0, 0.0, 1.0); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 0), 0.0, 3e-7); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 1), 0.0, 3e-7); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 2), 0.0, 3e-7); + } + { + vec3 lNg = normalize(vec3(0.0, 1.0, 1.0)); + float expect = 1.0 / (SHADOW_TILEMAP_RES * SHADOW_PAGE_RES); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 0), expect, 3e-7); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 1), expect * 2.0, 3e-7); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 2), expect * 4.0, 3e-7); + } + { + vec3 lNg = normalize(vec3(1.0, 1.0, 1.0)); + float expect = 2.0 / (SHADOW_TILEMAP_RES * SHADOW_PAGE_RES); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 0), expect, 3e-7); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 1), expect * 2.0, 3e-7); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 2), expect * 4.0, 3e-7); + } + light.clipmap_lod_min = -1; + { + vec3 lNg = normalize(vec3(1.0, 1.0, 1.0)); + float expect = 0.5 * (2.0 / (SHADOW_TILEMAP_RES * SHADOW_PAGE_RES)); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 0), expect, 3e-7); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 1), expect * 2.0, 3e-7); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP, vec2(0.0), 2), expect * 4.0, 3e-7); + } + } + + TEST(eevee_shadow, PunctualSlopeBias) + { + float near = 0.5, far = 1.0; + mat4 pers_mat = projection_perspective(-near, near, -near, near, near, far); + mat4 normal_mat = invert(transpose(pers_mat)); + + LightData light; + light.clip_near = floatBitsToInt(near); + light.clip_far = floatBitsToInt(far); + light.influence_radius_max = far; + light.type = LIGHT_SPOT; + light.normal_mat_packed.x = normal_mat[3][2]; + light.normal_mat_packed.y = normal_mat[3][3]; + + vec2 atlas_size = vec2(SHADOW_TILEMAP_RES); + { + /* Simulate a "2D" plane crossing the frustum diagonaly. */ + vec3 lP0 = vec3(-1.0, 0.0, -1.0); + vec3 lP1 = vec3(0.5, 0.0, -0.5); + vec3 lTg = normalize(lP1 - lP0); + vec3 lNg = vec3(-lTg.z, 0.0, lTg.x); + + float expect = 1.0 / (SHADOW_TILEMAP_RES * SHADOW_PAGE_RES); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 0), expect, 1e-4); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 1), expect * 2.0, 1e-4); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 2), expect * 4.0, 1e-4); + } + { + /* Simulate a "2D" plane crossing the near plane at the center diagonaly. */ + vec3 lP0 = vec3(-1.0, 0.0, -1.0); + vec3 lP1 = vec3(0.0, 0.0, -0.5); + vec3 lTg = normalize(lP1 - lP0); + vec3 lNg = vec3(-lTg.z, 0.0, lTg.x); + + float expect = 2.0 / (SHADOW_TILEMAP_RES * SHADOW_PAGE_RES); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 0), expect, 1e-4); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 1), expect * 2.0, 1e-4); + EXPECT_NEAR( + shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 2), expect * 4.0, 1e-4); + } + { + /* Simulate a "2D" plane parallel to near clip plane. */ + vec3 lP0 = vec3(-1.0, 0.0, -0.75); + vec3 lP1 = vec3(0.0, 0.0, -0.75); + vec3 lTg = normalize(lP1 - lP0); + vec3 lNg = vec3(-lTg.z, 0.0, lTg.x); + + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 0), 0.0, 1e-4); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 1), 0.0, 1e-4); + EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 2), 0.0, 1e-4); + } + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_bounds_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_bounds_comp.glsl new file mode 100644 index 00000000000..67559eeb47c --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_bounds_comp.glsl @@ -0,0 +1,77 @@ + +/** + * Virtual shadowmapping: Bounds computation for directional shadows. + * + * Iterate through all shadow casters and extract min/max per directional shadow. + * This needs to happen first in the pipeline to allow tagging all relevant tilemap as dirty if + * their range changes. + */ + +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_intersect_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl) + +shared int global_min; +shared int global_max; + +void main() +{ + uint index = gl_GlobalInvocationID.x; + /* Keep uniform control flow. Do not return. */ + index = min(index, uint(resource_len) - 1); + + uint resource_id = casters_id_buf[index]; + ObjectBounds bounds = bounds_buf[resource_id]; + IsectBox box = isect_data_setup(bounds.bounding_corners[0].xyz, + bounds.bounding_corners[1].xyz, + bounds.bounding_corners[2].xyz, + bounds.bounding_corners[3].xyz); + + LIGHT_FOREACH_BEGIN_DIRECTIONAL (light_cull_buf, l_idx) { + LightData light = light_buf[l_idx]; + + float local_min = FLT_MAX; + float local_max = -FLT_MAX; + for (int i = 0; i < 8; i++) { + float z = dot(box.corners[i].xyz, light._back); + local_min = min(local_min, z); + local_max = max(local_max, z); + } + + if (gl_LocalInvocationID.x == 0) { + global_min = floatBitsToOrderedInt(FLT_MAX); + global_max = floatBitsToOrderedInt(-FLT_MAX); + } + + barrier(); + + /* Quantization bias. */ + local_min -= abs(local_min) * 0.01; + local_max += abs(local_max) * 0.01; + + /* Intermediate result. Min/Max of a compute group. */ + atomicMin(global_min, floatBitsToOrderedInt(local_min)); + atomicMax(global_max, floatBitsToOrderedInt(local_max)); + + barrier(); + + if (gl_LocalInvocationID.x == 0) { + /* Final result. Min/Max of the whole dispatch. */ + atomicMin(light_buf[l_idx].clip_far, global_min); + atomicMax(light_buf[l_idx].clip_near, global_max); + /* TODO(fclem): This feel unecessary but we currently have no indexing from + * tilemap to lights. This is because the lights are selected by culling phase. */ + for (int i = light.tilemap_index; i <= light_tilemap_max_get(light); i++) { + int index = tilemaps_buf[i].clip_data_index; + atomicMin(tilemaps_clip_buf[index].clip_far, global_min); + atomicMax(tilemaps_clip_buf[index].clip_near, global_max); + } + } + + /* No need for barrier here since global_min/max is only read by thread 0 before being reset by + * thread 0. */ + } + LIGHT_FOREACH_END +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_finalize_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_finalize_comp.glsl new file mode 100644 index 00000000000..ef689588337 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_finalize_comp.glsl @@ -0,0 +1,181 @@ + +/** + * Virtual shadowmapping: Tilemap to texture conversion. + * + * For all visible light tilemaps, copy page coordinate to a texture. + * This avoids one level of indirection when evaluating shadows and allows + * to use a sampler instead of a SSBO bind. + */ + +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +shared uint tile_updates_count; +shared int view_index; + +void page_clear_buf_append(uint page_packed) +{ + uint clear_page_index = atomicAdd(clear_dispatch_buf.num_groups_z, 1u); + clear_page_buf[clear_page_index] = page_packed; +} + +void page_tag_as_rendered(ivec2 tile_co, int tiles_index, int lod) +{ + int tile_index = shadow_tile_offset(tile_co, tiles_index, lod); + tiles_buf[tile_index] |= SHADOW_IS_RENDERED; + atomicAdd(statistics_buf.page_rendered_count, 1); +} + +void main() +{ + if (all(equal(gl_LocalInvocationID, uvec3(0)))) { + tile_updates_count = uint(0); + } + barrier(); + + int tilemap_index = int(gl_GlobalInvocationID.z); + ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy); + + ivec2 atlas_texel = shadow_tile_coord_in_atlas(tile_co, tilemap_index); + + ShadowTileMapData tilemap_data = tilemaps_buf[tilemap_index]; + int lod_max = (tilemap_data.projection_type == SHADOW_PROJECTION_CUBEFACE) ? SHADOW_TILEMAP_LOD : + 0; + + int lod_valid = 0; + /* One bit per lod. */ + int do_lod_update = 0; + /* Packed page (packUvec2x16) to render per LOD. */ + uint updated_lod_page[SHADOW_TILEMAP_LOD + 1]; + uvec2 page_valid; + /* With all threads (LOD0 size dispatch) load each lod tile from the highest lod + * to the lowest, keeping track of the lowest one allocated which will be use for shadowing. + * Also save which page are to be updated. */ + for (int lod = SHADOW_TILEMAP_LOD; lod >= 0; lod--) { + if (lod > lod_max) { + updated_lod_page[lod] = 0xFFFFFFFFu; + continue; + } + + int tile_index = shadow_tile_offset(tile_co >> lod, tilemap_data.tiles_index, lod); + + ShadowTileData tile = shadow_tile_unpack(tiles_buf[tile_index]); + + if (tile.is_used && tile.do_update) { + do_lod_update = 1 << lod; + updated_lod_page[lod] = packUvec2x16(tile.page); + } + else { + updated_lod_page[lod] = 0xFFFFFFFFu; + } + + /* Save highest lod for this thread. */ + if (tile.is_used && lod > 0) { + /* Reload the page in case there was an allocation in the valid thread. */ + page_valid = tile.page; + lod_valid = lod; + } + else if (lod == 0 && lod_valid != 0 && !tile.is_allocated) { + /* If the tile is not used, store the valid LOD level in LOD0. */ + tile.page = page_valid; + tile.lod = lod_valid; + /* This is not a real ownership. It is just a tag so that the shadowing is deemed correct. */ + tile.is_allocated = true; + } + + if (lod == 0) { + imageStore(tilemaps_img, atlas_texel, uvec4(shadow_tile_pack(tile))); + } + } + + if (do_lod_update > 0) { + atomicAdd(tile_updates_count, 1u); + } + + barrier(); + + if (all(equal(gl_LocalInvocationID, uvec3(0)))) { + /* No update by default. */ + view_index = 64; + + if (tile_updates_count > 0) { + view_index = atomicAdd(pages_infos_buf.view_count, 1); + if (view_index < 64) { + view_infos_buf[view_index].viewmat = tilemap_data.viewmat; + view_infos_buf[view_index].viewinv = inverse(tilemap_data.viewmat); + + if (tilemap_data.projection_type != SHADOW_PROJECTION_CUBEFACE) { + int clip_index = tilemap_data.clip_data_index; + /* For directionnal, we need to modify winmat to encompass all casters. */ + float clip_far = -tilemaps_clip_buf[clip_index].clip_far_stored; + float clip_near = -tilemaps_clip_buf[clip_index].clip_near_stored; + tilemap_data.winmat[2][2] = -2.0 / (clip_far - clip_near); + tilemap_data.winmat[3][2] = -(clip_far + clip_near) / (clip_far - clip_near); + } + view_infos_buf[view_index].winmat = tilemap_data.winmat; + view_infos_buf[view_index].wininv = inverse(tilemap_data.winmat); + } + } + } + + barrier(); + + if (view_index < 64) { + ivec3 render_map_texel = ivec3(tile_co, view_index); + + /* Store page indirection for rendering. Update every texel in the view array level. */ + if (true) { + imageStore(render_map_lod0_img, render_map_texel, uvec4(updated_lod_page[0])); + if (updated_lod_page[0] != 0xFFFFFFFFu) { + page_clear_buf_append(updated_lod_page[0]); + page_tag_as_rendered(render_map_texel.xy, tilemap_data.tiles_index, 0); + } + } + render_map_texel.xy >>= 1; + if (all(equal(tile_co, render_map_texel.xy << 1u))) { + imageStore(render_map_lod1_img, render_map_texel, uvec4(updated_lod_page[1])); + if (updated_lod_page[1] != 0xFFFFFFFFu) { + page_clear_buf_append(updated_lod_page[1]); + page_tag_as_rendered(render_map_texel.xy, tilemap_data.tiles_index, 1); + } + } + render_map_texel.xy >>= 1; + if (all(equal(tile_co, render_map_texel.xy << 2u))) { + imageStore(render_map_lod2_img, render_map_texel, uvec4(updated_lod_page[2])); + if (updated_lod_page[2] != 0xFFFFFFFFu) { + page_clear_buf_append(updated_lod_page[2]); + page_tag_as_rendered(render_map_texel.xy, tilemap_data.tiles_index, 2); + } + } + render_map_texel.xy >>= 1; + if (all(equal(tile_co, render_map_texel.xy << 3u))) { + imageStore(render_map_lod3_img, render_map_texel, uvec4(updated_lod_page[3])); + if (updated_lod_page[3] != 0xFFFFFFFFu) { + page_clear_buf_append(updated_lod_page[3]); + page_tag_as_rendered(render_map_texel.xy, tilemap_data.tiles_index, 3); + } + } + render_map_texel.xy >>= 1; + if (all(equal(tile_co, render_map_texel.xy << 4u))) { + imageStore(render_map_lod4_img, render_map_texel, uvec4(updated_lod_page[4])); + if (updated_lod_page[4] != 0xFFFFFFFFu) { + page_clear_buf_append(updated_lod_page[4]); + page_tag_as_rendered(render_map_texel.xy, tilemap_data.tiles_index, 4); + } + } + render_map_texel.xy >>= 1; + if (all(equal(tile_co, render_map_texel.xy << 5u))) { + imageStore(render_map_lod5_img, render_map_texel, uvec4(updated_lod_page[5])); + if (updated_lod_page[5] != 0xFFFFFFFFu) { + page_clear_buf_append(updated_lod_page[5]); + page_tag_as_rendered(render_map_texel.xy, tilemap_data.tiles_index, 5); + } + } + } + + if (all(equal(gl_GlobalInvocationID, uvec3(0)))) { + /* Clamp it as it can underflow if there is too much tile present on screen. */ + pages_infos_buf.page_free_count = max(pages_infos_buf.page_free_count, 0); + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_init_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_init_comp.glsl new file mode 100644 index 00000000000..13ed490c77f --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_init_comp.glsl @@ -0,0 +1,93 @@ + +/** + * Virtual shadowmapping: Setup phase for tilemaps. + * + * Clear the usage flag. + * Also tag for update shifted tiles for directional shadow clipmaps. + * Dispatched with one local thread per LOD0 tile and one workgroup per tilemap. + */ + +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl) + +shared int directional_range_changed; + +ShadowTileDataPacked init_tile_data(ShadowTileDataPacked tile, bool do_update) +{ + if (flag_test(tile, SHADOW_IS_RENDERED)) { + tile &= ~(SHADOW_DO_UPDATE | SHADOW_IS_RENDERED); + } + if (do_update) { + tile |= SHADOW_DO_UPDATE; + } + tile &= ~SHADOW_IS_USED; + return tile; +} + +void main() +{ + uint tilemap_index = gl_GlobalInvocationID.z; + ShadowTileMapData tilemap = tilemaps_buf[tilemap_index]; + + barrier(); + + if (all(equal(gl_LocalInvocationID, uvec3(0)))) { + /* Reset shift to not tag for update more than once per sync cycle. */ + tilemaps_buf[tilemap_index].grid_shift = ivec2(0); + + if (tilemap.projection_type != SHADOW_PROJECTION_CUBEFACE) { + int clip_index = tilemap.clip_data_index; + ShadowTileMapClip clip_data = tilemaps_clip_buf[clip_index]; + float clip_near_new = orderedIntBitsToFloat(clip_data.clip_near); + float clip_far_new = orderedIntBitsToFloat(clip_data.clip_far); + bool near_changed = clip_near_new != clip_data.clip_near_stored; + bool far_changed = clip_far_new != clip_data.clip_far_stored; + directional_range_changed = int(near_changed || far_changed); + /* NOTE(fclem): This assumes clip near/far are computed each time the init phase runs. */ + tilemaps_clip_buf[clip_index].clip_near_stored = clip_near_new; + tilemaps_clip_buf[clip_index].clip_far_stored = clip_far_new; + /* Reset for next update. */ + tilemaps_clip_buf[clip_index].clip_near = floatBitsToOrderedInt(-FLT_MAX); + tilemaps_clip_buf[clip_index].clip_far = floatBitsToOrderedInt(FLT_MAX); + } + } + + barrier(); + + ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy); + ivec2 tile_shifted = tile_co + tilemap.grid_shift; + ivec2 tile_wrapped = ivec2(tile_shifted % SHADOW_TILEMAP_RES); + + /* If this tile was shifted in and contains old information, update it. + * Note that cubemap always shift all tiles on update. */ + bool do_update = !in_range_inclusive(tile_shifted, ivec2(0), ivec2(SHADOW_TILEMAP_RES - 1)); + + /* TODO(fclem): Might be better to resize the depth stored instead of a full render update. */ + if (tilemap.projection_type != SHADOW_PROJECTION_CUBEFACE && directional_range_changed != 0) { + do_update = true; + } + + int lod_max = (tilemap.projection_type == SHADOW_PROJECTION_CUBEFACE) ? SHADOW_TILEMAP_LOD : 0; + uint lod_size = uint(SHADOW_TILEMAP_RES); + for (int lod = 0; lod <= lod_max; lod++, lod_size >>= 1u) { + bool thread_active = all(lessThan(tile_co, ivec2(lod_size))); + ShadowTileDataPacked tile; + int tile_load = shadow_tile_offset(tile_wrapped, tilemap.tiles_index, lod); + if (thread_active) { + tile = init_tile_data(tiles_buf[tile_load], do_update); + } + + /* Uniform control flow for barrier. Needed to avoid race condition on shifted loads. */ + barrier(); + + if (thread_active) { + int tile_store = shadow_tile_offset(tile_co, tilemap.tiles_index, lod); + if ((tile_load != tile_store) && flag_test(tile, SHADOW_IS_CACHED)) { + /* Inlining of shadow_page_cache_update_tile_ref to avoid buffer depedencies. */ + pages_cached_buf[shadow_tile_unpack(tile).cache_index].y = tile_store; + } + tiles_buf[tile_store] = tile; + } + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_lib.glsl new file mode 100644 index 00000000000..17efe37fe35 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_tilemap_lib.glsl @@ -0,0 +1,237 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_shape_lib.glsl) + +/* ---------------------------------------------------------------------- */ +/** \name Tilemap data + * \{ */ + +int shadow_tile_index(ivec2 tile) +{ + return tile.x + tile.y * SHADOW_TILEMAP_RES; +} + +ivec2 shadow_tile_coord(int tile_index) +{ + return ivec2(tile_index % SHADOW_TILEMAP_RES, tile_index / SHADOW_TILEMAP_RES); +} + +/* Return bottom left pixel position of the tilemap inside the tilemap atlas. */ +ivec2 shadow_tilemap_start(int tilemap_index) +{ + return SHADOW_TILEMAP_RES * + ivec2(tilemap_index % SHADOW_TILEMAP_PER_ROW, tilemap_index / SHADOW_TILEMAP_PER_ROW); +} + +ivec2 shadow_tile_coord_in_atlas(ivec2 tile, int tilemap_index) +{ + return shadow_tilemap_start(tilemap_index) + tile; +} + +/** + * Return tile index inside `tiles_buf` for a given tile coordinate inside a specific LOD. + * `tiles_index` should be `ShadowTileMapData.tiles_index`. + */ +int shadow_tile_offset(ivec2 tile, int tiles_index, int lod) +{ +#if SHADOW_TILEMAP_LOD != 5 +# error This needs to be adjusted +#endif + const int lod0_width = SHADOW_TILEMAP_RES / 1; + const int lod1_width = SHADOW_TILEMAP_RES / 2; + const int lod2_width = SHADOW_TILEMAP_RES / 4; + const int lod3_width = SHADOW_TILEMAP_RES / 8; + const int lod4_width = SHADOW_TILEMAP_RES / 16; + const int lod5_width = SHADOW_TILEMAP_RES / 32; + const int lod0_size = lod0_width * lod0_width; + const int lod1_size = lod1_width * lod1_width; + const int lod2_size = lod2_width * lod2_width; + const int lod3_size = lod3_width * lod3_width; + const int lod4_size = lod4_width * lod4_width; + const int lod5_size = lod5_width * lod5_width; + + int offset = tiles_index; + switch (lod) { + case 5: + offset += lod0_size + lod1_size + lod2_size + lod3_size + lod4_size; + offset += tile.y * lod5_width; + break; + case 4: + offset += lod0_size + lod1_size + lod2_size + lod3_size; + offset += tile.y * lod4_width; + break; + case 3: + offset += lod0_size + lod1_size + lod2_size; + offset += tile.y * lod3_width; + break; + case 2: + offset += lod0_size + lod1_size; + offset += tile.y * lod2_width; + break; + case 1: + offset += lod0_size; + offset += tile.y * lod1_width; + break; + case 0: + default: + offset += tile.y * lod0_width; + break; + } + offset += tile.x; + return offset; +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Load / Store functions. + * \{ */ + +/** \note: Will clamp if out of bounds. */ +ShadowTileData shadow_tile_load(usampler2D tilemaps_tx, ivec2 tile_co, int tilemap_index) +{ + /* NOTE(@fclem): This clamp can hide some small imprecision at clipmap transition. + * Can be disabled to check if the clipmap is well centered. */ + tile_co = clamp(tile_co, ivec2(0), ivec2(SHADOW_TILEMAP_RES - 1)); + uint tile_data = + texelFetch(tilemaps_tx, shadow_tile_coord_in_atlas(tile_co, tilemap_index), 0).x; + return shadow_tile_unpack(tile_data); +} + +/* This function should be the inverse of ShadowDirectional::coverage_get(). */ +int shadow_directional_level(LightData light, vec3 lP) +{ + float lod; + if (light.type == LIGHT_SUN) { + /* We need to hide one tile worth of data to hide the moving transition. */ + const float narrowing = float(SHADOW_TILEMAP_RES) / (float(SHADOW_TILEMAP_RES) - 1.0001); + /* Since the distance is centered around the camera (and thus by extension the tilemap), + * we need to multiply by 2 to get the lod level which covers the following range: + * [-coverage_get(lod)/2..coverage_get(lod)/2] */ + lod = log2(length(lP) * narrowing * 2.0); + } + else { + /* The narrowing need to be stronger since the tilemap position is not rounded but floored. */ + const float narrowing = float(SHADOW_TILEMAP_RES) / (float(SHADOW_TILEMAP_RES) - 2.5001); + /* Since we want half of the size, bias the level by -1. */ + float lod_min_half_size = exp2(float(light.clipmap_lod_min - 1)); + lod = length(lP.xy) * narrowing / lod_min_half_size; + } + int clipmap_lod = int(ceil(lod + light._clipmap_lod_bias)); + return clamp(clipmap_lod, light.clipmap_lod_min, light.clipmap_lod_max); +} + +struct ShadowCoordinates { + /* Index of the tilemap to containing the tile. */ + int tilemap_index; + /* LOD of the tile to load relative to the min level. Always positive. */ + int lod_relative; + /* Tile coordinate inside the tilemap. */ + ivec2 tile_coord; + /* UV coordinates in [0..SHADOW_TILEMAP_RES) range. */ + vec2 uv; +}; + +/* Retain sign bit and avoid costly int division. */ +ivec2 shadow_decompress_grid_offset(eLightType light_type, ivec2 offset, int level_relative) +{ + if (light_type == LIGHT_SUN_ORTHO) { + return shadow_cascade_grid_offset(offset, level_relative); + } + else { + return ((offset & 0xFFFF) >> level_relative) - ((offset >> 16) >> level_relative); + } +} + +/** + * \a lP shading point position in light space (world unit) and translated to camera position + * snapped to smallest clipmap level. + */ +ShadowCoordinates shadow_directional_coordinates(LightData light, vec3 lP) +{ + ShadowCoordinates ret; + + int level = shadow_directional_level(light, lP - light._position); + /* This difference needs to be less than 32 for the later shift to be valid. + * This is ensured by ShadowDirectional::clipmap_level_range(). */ + int level_relative = level - light.clipmap_lod_min; + + ret.tilemap_index = light.tilemap_index + level_relative; + + ret.lod_relative = (light.type == LIGHT_SUN_ORTHO) ? light.clipmap_lod_min : level; + + /* Compute offset in tile. */ + ivec2 clipmap_offset = shadow_decompress_grid_offset( + light.type, light.clipmap_base_offset, level_relative); + + ret.uv = lP.xy - vec2(light._clipmap_origin_x, light._clipmap_origin_y); + ret.uv /= exp2(float(ret.lod_relative)); + ret.uv = ret.uv * float(SHADOW_TILEMAP_RES) + float(SHADOW_TILEMAP_RES / 2); + ret.uv -= vec2(clipmap_offset); + /* Clamp to avoid out of tilemap access. */ + ret.tile_coord = clamp(ivec2(ret.uv), ivec2(0.0), ivec2(SHADOW_TILEMAP_RES - 1)); + return ret; +} + +/* Transform vector to face local coordinate. */ +vec3 shadow_punctual_local_position_to_face_local(int face_id, vec3 lL) +{ + switch (face_id) { + case 1: + return vec3(-lL.y, lL.z, -lL.x); + case 2: + return vec3(lL.y, lL.z, lL.x); + case 3: + return vec3(lL.x, lL.z, -lL.y); + case 4: + return vec3(-lL.x, lL.z, lL.y); + case 5: + return vec3(lL.x, -lL.y, -lL.z); + default: + return lL; + } +} + +/** + * \a lP shading point position in face local space (world unit). + * \a face_id is the one used to rotate lP using shadow_punctual_local_position_to_face_local(). + */ +ShadowCoordinates shadow_punctual_coordinates(LightData light, vec3 lP, int face_id) +{ + ShadowCoordinates ret; + ret.tilemap_index = light.tilemap_index + face_id; + /* UVs in [-1..+1] range. */ + ret.uv = lP.xy / abs(lP.z); + /* UVs in [0..SHADOW_TILEMAP_RES] range. */ + ret.uv = ret.uv * float(SHADOW_TILEMAP_RES / 2) + float(SHADOW_TILEMAP_RES / 2); + /* Clamp to avoid out of tilemap access. */ + ret.tile_coord = clamp(ivec2(ret.uv), ivec2(0), ivec2(SHADOW_TILEMAP_RES - 1)); + return ret; +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Frustum shapes. + * \{ */ + +vec3 shadow_tile_corner_persp(ShadowTileMapData tilemap, ivec2 tile) +{ + return tilemap.corners[1].xyz + tilemap.corners[2].xyz * float(tile.x) + + tilemap.corners[3].xyz * float(tile.y); +} + +Pyramid shadow_tilemap_cubeface_bounds(ShadowTileMapData tilemap, + ivec2 tile_start, + const ivec2 extent) +{ + Pyramid shape; + shape.corners[0] = tilemap.corners[0].xyz; + shape.corners[1] = shadow_tile_corner_persp(tilemap, tile_start + ivec2(0, 0)); + shape.corners[2] = shadow_tile_corner_persp(tilemap, tile_start + ivec2(extent.x, 0)); + shape.corners[3] = shadow_tile_corner_persp(tilemap, tile_start + extent); + shape.corners[4] = shadow_tile_corner_persp(tilemap, tile_start + ivec2(0, extent.y)); + return shape; +} + +/** \} */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl index f35e9135996..13d2a2d0021 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl @@ -10,6 +10,7 @@ #pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl) #pragma BLENDER_REQUIRE(eevee_surf_lib.glsl) #pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_transparency_lib.glsl) vec4 closure_to_rgba(Closure cl) { @@ -23,50 +24,6 @@ vec4 closure_to_rgba(Closure cl) return out_color; } -/* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire. */ -float hash(vec2 a) -{ - return fract(1e4 * sin(17.0 * a.x + 0.1 * a.y) * (0.1 + abs(sin(13.0 * a.y + a.x)))); -} - -float hash3d(vec3 a) -{ - return hash(vec2(hash(a.xy), a.z)); -} - -float hashed_alpha_threshold(float hash_scale, float hash_offset, vec3 P) -{ - /* Find the discretized derivatives of our coordinates. */ - float max_deriv = max(length(dFdx(P)), length(dFdy(P))); - float pix_scale = 1.0 / (hash_scale * max_deriv); - /* Find two nearest log-discretized noise scales. */ - float pix_scale_log = log2(pix_scale); - vec2 pix_scales; - pix_scales.x = exp2(floor(pix_scale_log)); - pix_scales.y = exp2(ceil(pix_scale_log)); - /* Compute alpha thresholds at our two noise scales. */ - vec2 alpha; - alpha.x = hash3d(floor(pix_scales.x * P)); - alpha.y = hash3d(floor(pix_scales.y * P)); - /* Factor to interpolate lerp with. */ - float fac = fract(log2(pix_scale)); - /* Interpolate alpha threshold from noise at two scales. */ - float x = mix(alpha.x, alpha.y, fac); - /* Pass into CDF to compute uniformly distrib threshold. */ - float a = min(fac, 1.0 - fac); - float one_a = 1.0 - a; - float denom = 1.0 / (2 * a * one_a); - float one_x = (1 - x); - vec3 cases = vec3((x * x) * denom, (x - 0.5 * a) / one_a, 1.0 - (one_x * one_x * denom)); - /* Find our final, uniformly distributed alpha threshold. */ - float threshold = (x < one_a) ? ((x < a) ? cases.x : cases.y) : cases.z; - /* Jitter the threshold for TAA accumulation. */ - threshold = fract(threshold + hash_offset); - /* Avoids threshold == 0. */ - threshold = clamp(threshold, 1.0e-6, 1.0); - return threshold; -} - void main() { #ifdef MAT_TRANSPARENT @@ -75,7 +32,7 @@ void main() nodetree_surface(); float noise_offset = sampling_rng_1D_get(SAMPLING_TRANSPARENCY); - float random_threshold = hashed_alpha_threshold(1.0, noise_offset, g_data.P); + float random_threshold = transparency_hashed_alpha_threshold(1.0, noise_offset, g_data.P); float transparency = avg(g_transmittance); if (transparency > random_threshold) { diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl index ab29067763d..dad1faad0b4 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl @@ -24,6 +24,7 @@ vec4 closure_to_rgba(Closure cl) light_eval(g_diffuse_data, g_reflection_data, g_data.P, + g_data.Ng, cameraVec(g_data.P), vP_z, 0.01 /* TODO(fclem) thickness. */, @@ -66,6 +67,7 @@ void main() light_eval(g_diffuse_data, g_reflection_data, g_data.P, + g_data.Ng, cameraVec(g_data.P), vP_z, 0.01 /* TODO(fclem) thickness. */, diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl new file mode 100644 index 00000000000..65b79b821fe --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl @@ -0,0 +1,91 @@ + +/** + * Virtual Shadow map output. + * + * Meshes are rasterize onto an empty framebuffer. Each generated fragment then checks which + * virtual page it is supposed to go and load the physical page adress. + * If a physical page exists, we then use atomicMin to mimic a less-than depth test and write to + * the destination texel. + **/ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_transparency_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl) + +void write_depth(ivec2 texel_co, const int lod, ivec2 tile_co, float depth) +{ + ivec2 texel_co_lod = texel_co >> lod; + + ivec2 lod_corner_in_lod0 = texel_co_lod << lod; + /* Add half of the lod to get the top right pixel nearest to the lod pixel. + * This way we never get more than half a LOD0 pixel of offset from the center of any LOD. + * This offset is taken into account during sampling. */ + const int lod_half_stride_in_lod0 = (1 << lod) / 2; + ivec2 closest_lod0_texel = lod_corner_in_lod0 + lod_half_stride_in_lod0; + + if (!all(equal(closest_lod0_texel, texel_co))) { + return; + } + + ivec3 render_map_coord = ivec3(tile_co >> lod, shadow_interp.view_id); + uint page_packed = texelFetch(shadow_render_map_tx, render_map_coord, lod).r; + /* Return if no valid page. */ + if (page_packed == 0xFFFFFFFFu) { + return; + } + ivec2 page = ivec2(unpackUvec2x16(page_packed)); + ivec2 texel_in_page = texel_co_lod % pages_infos_buf.page_size; + ivec2 out_texel = page * pages_infos_buf.page_size + texel_in_page; + + uint u_depth = floatBitsToUint(depth); + /* Quantization bias. Equivalent to nextafter in C without all the safety. 1 is not enough. */ + u_depth += 2; + + imageAtomicMin(shadow_atlas_img, out_texel, u_depth); +} + +void main() +{ +#ifdef MAT_TRANSPARENT + init_globals(); + + nodetree_surface(); + + float noise_offset = sampling_rng_1D_get(SAMPLING_TRANSPARENCY); + float random_threshold = transparency_hashed_alpha_threshold(1.0, noise_offset, g_data.P); + + float transparency = avg(g_transmittance); + if (transparency > random_threshold) { + discard; + return; + } +#endif + + drw_view_id = shadow_interp.view_id; + + ivec2 texel_co = ivec2(gl_FragCoord.xy); + ivec2 tile_co = texel_co / pages_infos_buf.page_size; + + float depth = gl_FragCoord.z; + float slope_bias = fwidth(depth); + write_depth(texel_co, 0, tile_co, depth + slope_bias); + + /* Only needed for local lights. */ + bool is_persp = (drw_view.winmat[3][3] == 0.0); + if (is_persp) { + /* Note that even if texel center is offset, we store unmodified depth. + * We increase bias instead at sampling time. */ +#if SHADOW_TILEMAP_LOD != 5 +# error This needs to be adjusted +#endif + write_depth(texel_co, 1, tile_co, depth + slope_bias * 2.0); + write_depth(texel_co, 2, tile_co, depth + slope_bias * 4.0); + write_depth(texel_co, 3, tile_co, depth + slope_bias * 8.0); + write_depth(texel_co, 4, tile_co, depth + slope_bias * 16.0); + write_depth(texel_co, 5, tile_co, depth + slope_bias * 32.0); + } +} diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_transparency_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_transparency_lib.glsl new file mode 100644 index 00000000000..6306a509e4c --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_transparency_lib.glsl @@ -0,0 +1,44 @@ + +/* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire. */ +float transparency_hash(vec2 a) +{ + return fract(1e4 * sin(17.0 * a.x + 0.1 * a.y) * (0.1 + abs(sin(13.0 * a.y + a.x)))); +} + +float transparency_hash_3d(vec3 a) +{ + return transparency_hash(vec2(transparency_hash(a.xy), a.z)); +} + +float transparency_hashed_alpha_threshold(float hash_scale, float hash_offset, vec3 P) +{ + /* Find the discretized derivatives of our coordinates. */ + float max_deriv = max(length(dFdx(P)), length(dFdy(P))); + float pix_scale = 1.0 / (hash_scale * max_deriv); + /* Find two nearest log-discretized noise scales. */ + float pix_scale_log = log2(pix_scale); + vec2 pix_scales; + pix_scales.x = exp2(floor(pix_scale_log)); + pix_scales.y = exp2(ceil(pix_scale_log)); + /* Compute alpha thresholds at our two noise scales. */ + vec2 alpha; + alpha.x = transparency_hash_3d(floor(pix_scales.x * P)); + alpha.y = transparency_hash_3d(floor(pix_scales.y * P)); + /* Factor to interpolate lerp with. */ + float fac = fract(log2(pix_scale)); + /* Interpolate alpha threshold from noise at two scales. */ + float x = mix(alpha.x, alpha.y, fac); + /* Pass into CDF to compute uniformly distrib threshold. */ + float a = min(fac, 1.0 - fac); + float one_a = 1.0 - a; + float denom = 1.0 / (2 * a * one_a); + float one_x = (1 - x); + vec3 cases = vec3((x * x) * denom, (x - 0.5 * a) / one_a, 1.0 - (one_x * one_x * denom)); + /* Find our final, uniformly distributed alpha threshold. */ + float threshold = (x < one_a) ? ((x < a) ? cases.x : cases.y) : cases.z; + /* Jitter the threshold for TAA accumulation. */ + threshold = fract(threshold + hash_offset); + /* Avoids threshold == 0. */ + threshold = clamp(threshold, 1.0e-6, 1.0); + return threshold; +} diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh index 7883bf01aeb..0ef16bf3522 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh @@ -40,7 +40,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_gpencil) .additional_info("eevee_shared") .define("MAT_GEOM_GPENCIL") .vertex_source("eevee_geom_gpencil_vert.glsl") - .additional_info("draw_gpencil", "draw_resource_id_varying", "draw_resource_handle"); + .additional_info("draw_gpencil", "draw_resource_id_varying", "draw_resource_id_new"); GPU_SHADER_CREATE_INFO(eevee_geom_curves) .additional_info("eevee_shared") @@ -49,7 +49,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_curves) .additional_info("draw_hair", "draw_curves_infos", "draw_resource_id_varying", - "draw_resource_handle"); + "draw_resource_id_new"); GPU_SHADER_CREATE_INFO(eevee_geom_world) .additional_info("eevee_shared") @@ -95,8 +95,8 @@ GPU_SHADER_CREATE_INFO(eevee_render_pass_out) .image_out(RBUFS_EMISSION_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img"); GPU_SHADER_CREATE_INFO(eevee_cryptomatte_out) - .storage_buf(7, Qualifier::READ, "vec2", "cryptomatte_object_buf[]", Frequency::PASS) - .image_out(7, Qualifier::WRITE, GPU_RGBA32F, "rp_cryptomatte_img"); + .storage_buf(CRYPTOMATTE_BUF_SLOT, Qualifier::READ, "vec2", "cryptomatte_object_buf[]") + .image_out(RBUFS_CRYPTOMATTE_SLOT, Qualifier::WRITE, GPU_RGBA32F, "rp_cryptomatte_img"); GPU_SHADER_CREATE_INFO(eevee_surf_deferred) .vertex_out(eevee_surf_iface) @@ -128,14 +128,13 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward) .fragment_out(0, Type::VEC4, "out_radiance", DualBlend::SRC_0) .fragment_out(0, Type::VEC4, "out_transmittance", DualBlend::SRC_1) .fragment_source("eevee_surf_forward_frag.glsl") - .additional_info("eevee_cryptomatte_out", - "eevee_light_data", + .additional_info("eevee_light_data", "eevee_camera", "eevee_utility_texture", - "eevee_sampling_data" - // "eevee_lightprobe_data", - // "eevee_shadow_data" + "eevee_sampling_data", + "eevee_shadow_data" /* Optionally added depending on the material. */ + // "eevee_cryptomatte_out", // "eevee_raytrace_data", // "eevee_transmittance_data", // "eevee_aov_out", @@ -158,6 +157,23 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world) "eevee_camera", "eevee_utility_texture"); +GPU_SHADER_INTERFACE_INFO(eevee_shadow_iface, "shadow_interp").flat(Type::UINT, "view_id"); + +GPU_SHADER_CREATE_INFO(eevee_surf_shadow) + .define("DRW_VIEW_LEN", "64") + .define("MAT_SHADOW") + .vertex_out(eevee_surf_iface) + .vertex_out(eevee_shadow_iface) + .sampler(SHADOW_RENDER_MAP_SLOT, ImageType::UINT_2D_ARRAY, "shadow_render_map_tx") + .image(SHADOW_ATLAS_SLOT, + GPU_R32UI, + Qualifier::READ_WRITE, + ImageType::UINT_2D, + "shadow_atlas_img") + .storage_buf(SHADOW_PAGE_INFO_SLOT, Qualifier::READ, "ShadowPagesInfoData", "pages_infos_buf") + .fragment_source("eevee_surf_shadow_frag.glsl") + .additional_info("eevee_camera", "eevee_utility_texture", "eevee_sampling_data"); + #undef image_out #undef image_array_out @@ -210,7 +226,8 @@ GPU_SHADER_CREATE_INFO(eevee_material_stub).define("EEVEE_MATERIAL_STUBS"); EEVEE_MAT_GEOM_VARIATIONS(name##_world, "eevee_surf_world", __VA_ARGS__) \ EEVEE_MAT_GEOM_VARIATIONS(name##_depth, "eevee_surf_depth", __VA_ARGS__) \ EEVEE_MAT_GEOM_VARIATIONS(name##_deferred, "eevee_surf_deferred", __VA_ARGS__) \ - EEVEE_MAT_GEOM_VARIATIONS(name##_forward, "eevee_surf_forward", __VA_ARGS__) + EEVEE_MAT_GEOM_VARIATIONS(name##_forward, "eevee_surf_forward", __VA_ARGS__) \ + EEVEE_MAT_GEOM_VARIATIONS(name##_shadow, "eevee_surf_shadow", __VA_ARGS__) EEVEE_MAT_PIPE_VARIATIONS(eevee_surface, "eevee_material_stub") diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh new file mode 100644 index 00000000000..bb6b6d1e105 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh @@ -0,0 +1,176 @@ + +#include "eevee_defines.hh" + +#include "gpu_shader_create_info.hh" + +/* -------------------------------------------------------------------- */ +/** \name Shadow pipeline + * \{ */ + +GPU_SHADER_CREATE_INFO(eevee_shadow_tilemap_bounds) + .do_static_compilation(true) + .local_group_size(SHADOW_BOUNDS_GROUP_SIZE) + .storage_buf(LIGHT_BUF_SLOT, Qualifier::READ_WRITE, "LightData", "light_buf[]") + .storage_buf(LIGHT_CULL_BUF_SLOT, Qualifier::READ, "LightCullingData", "light_cull_buf") + .storage_buf(4, Qualifier::READ, "uint", "casters_id_buf[]") + .storage_buf(5, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(6, Qualifier::READ, "ObjectBounds", "bounds_buf[]") + .storage_buf(7, Qualifier::READ_WRITE, "ShadowTileMapClip", "tilemaps_clip_buf[]") + .push_constant(Type::INT, "resource_len") + .typedef_source("draw_shader_shared.h") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_tilemap_bounds_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_tilemap_init) + .do_static_compilation(true) + .local_group_size(SHADOW_TILEMAP_RES, SHADOW_TILEMAP_RES) + .storage_buf(0, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .storage_buf(2, Qualifier::READ_WRITE, "ShadowTileMapClip", "tilemaps_clip_buf[]") + .storage_buf(4, Qualifier::READ_WRITE, "uvec2", "pages_cached_buf[]") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_tilemap_init_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_tag_update) + .do_static_compilation(true) + .local_group_size(1, 1, 1) + .storage_buf(0, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .storage_buf(5, Qualifier::READ, "ObjectBounds", "bounds_buf[]") + .storage_buf(6, Qualifier::READ, "uint", "resource_ids_buf[]") + .additional_info("eevee_shared", "draw_view", "draw_view_culling") + .compute_source("eevee_shadow_tag_update_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_tag_usage_opaque) + .do_static_compilation(true) + .local_group_size(SHADOW_DEPTH_SCAN_GROUP_SIZE, SHADOW_DEPTH_SCAN_GROUP_SIZE) + .sampler(0, ImageType::DEPTH_2D, "depth_tx") + .storage_buf(5, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(6, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .push_constant(Type::FLOAT, "tilemap_projection_ratio") + .additional_info("eevee_shared", "draw_view", "draw_view_culling", "eevee_light_data") + .compute_source("eevee_shadow_tag_usage_comp.glsl"); + +GPU_SHADER_INTERFACE_INFO(eevee_shadow_tag_transparent_iface, "interp") + .smooth(Type::VEC3, "P") + .smooth(Type::VEC3, "vP"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_tag_usage_transparent) + .do_static_compilation(true) + .vertex_in(0, Type::VEC3, "pos") + .storage_buf(4, Qualifier::READ, "ObjectBounds", "bounds_buf[]") + .storage_buf(5, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(6, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .push_constant(Type::FLOAT, "tilemap_projection_ratio") + .vertex_out(eevee_shadow_tag_transparent_iface) + .additional_info( + "eevee_shared", "draw_view", "draw_view_culling", "draw_modelmat_new", "eevee_light_data") + .vertex_source("eevee_shadow_tag_usage_vert.glsl") + .fragment_source("eevee_shadow_tag_usage_frag.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_page_mask) + .do_static_compilation(true) + .local_group_size(SHADOW_TILEMAP_RES, SHADOW_TILEMAP_RES) + .storage_buf(0, Qualifier::READ, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_page_mask_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_page_free) + .do_static_compilation(true) + .local_group_size(SHADOW_TILEMAP_LOD0_LEN) + .storage_buf(0, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .storage_buf(2, Qualifier::READ_WRITE, "ShadowPagesInfoData", "pages_infos_buf") + .storage_buf(3, Qualifier::READ_WRITE, "uint", "pages_free_buf[]") + .storage_buf(4, Qualifier::READ_WRITE, "uvec2", "pages_cached_buf[]") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_page_free_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_page_defrag) + .do_static_compilation(true) + .local_group_size(1) + .typedef_source("draw_shader_shared.h") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .storage_buf(2, Qualifier::READ_WRITE, "ShadowPagesInfoData", "pages_infos_buf") + .storage_buf(3, Qualifier::READ_WRITE, "uint", "pages_free_buf[]") + .storage_buf(4, Qualifier::READ_WRITE, "uvec2", "pages_cached_buf[]") + .storage_buf(5, Qualifier::WRITE, "DispatchCommand", "clear_dispatch_buf") + .storage_buf(6, Qualifier::READ_WRITE, "ShadowStatistics", "statistics_buf") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_page_defrag_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_page_allocate) + .do_static_compilation(true) + .local_group_size(SHADOW_TILEMAP_LOD0_LEN) + .typedef_source("draw_shader_shared.h") + .storage_buf(0, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .storage_buf(2, Qualifier::READ_WRITE, "ShadowPagesInfoData", "pages_infos_buf") + .storage_buf(3, Qualifier::READ_WRITE, "uint", "pages_free_buf[]") + .storage_buf(4, Qualifier::READ_WRITE, "uvec2", "pages_cached_buf[]") + .storage_buf(6, Qualifier::READ_WRITE, "ShadowStatistics", "statistics_buf") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_page_allocate_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_tilemap_finalize) + .do_static_compilation(true) + .typedef_source("draw_shader_shared.h") + .local_group_size(SHADOW_TILEMAP_RES, SHADOW_TILEMAP_RES) + .storage_buf(0, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(1, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]") + .storage_buf(2, Qualifier::READ_WRITE, "ShadowPagesInfoData", "pages_infos_buf") + .storage_buf(3, Qualifier::WRITE, "ViewMatrices", "view_infos_buf[64]") + .storage_buf(4, Qualifier::READ_WRITE, "ShadowStatistics", "statistics_buf") + .storage_buf(5, Qualifier::READ_WRITE, "DispatchCommand", "clear_dispatch_buf") + .storage_buf(6, Qualifier::READ_WRITE, "uint", "clear_page_buf[]") + .storage_buf(7, Qualifier::READ_WRITE, "ShadowTileMapClip", "tilemaps_clip_buf[]") + .image(0, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D, "tilemaps_img") + .image(1, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D_ARRAY, "render_map_lod0_img") + .image(2, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D_ARRAY, "render_map_lod1_img") + .image(3, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D_ARRAY, "render_map_lod2_img") + .image(4, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D_ARRAY, "render_map_lod3_img") + .image(5, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D_ARRAY, "render_map_lod4_img") + .image(6, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D_ARRAY, "render_map_lod5_img") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_tilemap_finalize_comp.glsl"); + +GPU_SHADER_CREATE_INFO(eevee_shadow_page_clear) + .do_static_compilation(true) + .local_group_size(SHADOW_PAGE_CLEAR_GROUP_SIZE, SHADOW_PAGE_CLEAR_GROUP_SIZE) + .storage_buf(2, Qualifier::READ, "ShadowPagesInfoData", "pages_infos_buf") + .storage_buf(6, Qualifier::READ, "uint", "clear_page_buf[]") + .image(0, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D, "atlas_img") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_page_clear_comp.glsl"); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shadow resources + * \{ */ + +GPU_SHADER_CREATE_INFO(eevee_shadow_data) + .sampler(SHADOW_ATLAS_TEX_SLOT, ImageType::UINT_2D, "shadow_atlas_tx") + .sampler(SHADOW_TILEMAPS_TEX_SLOT, ImageType::UINT_2D, "shadow_tilemaps_tx"); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Debug + * \{ */ + +GPU_SHADER_CREATE_INFO(eevee_shadow_debug) + .do_static_compilation(true) + .additional_info("eevee_shared") + .storage_buf(5, Qualifier::READ, "ShadowTileMapData", "tilemaps_buf[]") + .storage_buf(6, Qualifier::READ, "ShadowTileDataPacked", "tiles_buf[]") + .fragment_out(0, Type::VEC4, "out_color_add", DualBlend::SRC_0) + .fragment_out(0, Type::VEC4, "out_color_mul", DualBlend::SRC_1) + .push_constant(Type::INT, "debug_mode") + .push_constant(Type::INT, "debug_tilemap_index") + .fragment_source("eevee_shadow_debug_frag.glsl") + .additional_info( + "draw_fullscreen", "draw_view", "eevee_hiz_data", "eevee_light_data", "eevee_shadow_data"); + +/** \} */ diff --git a/source/blender/draw/engines/overlay/overlay_armature.cc b/source/blender/draw/engines/overlay/overlay_armature.cc index 8c9587e7a9a..674ce4ceb4d 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.cc +++ b/source/blender/draw/engines/overlay/overlay_armature.cc @@ -1486,7 +1486,7 @@ static void draw_axes(ArmatureDrawContext *ctx, if (pchan && pchan->custom && !(arm->flag & ARM_NO_CUSTOM)) { /* Special case: Custom bones can have different scale than the bone. - * Recompute display matrix without the custom scaling applied. (T65640). */ + * Recompute display matrix without the custom scaling applied. (#65640). */ float axis_mat[4][4]; float length = pchan->bone->length; copy_m4_m4(axis_mat, pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat); @@ -2096,7 +2096,7 @@ static void draw_bone_name(ArmatureDrawContext *ctx, /* -------------------------------------------------------------------- */ /** \name Pose Bone Culling * - * Used for selection since drawing many bones can be slow, see: T91253. + * Used for selection since drawing many bones can be slow, see: #91253. * * Bounding spheres are used with margins added to ensure bones are included. * An added margin is needed because #BKE_pchan_minmax only returns the bounds @@ -2229,9 +2229,9 @@ static void draw_armature_edit(ArmatureDrawContext *ctx) const bool show_text = DRW_state_show_text(); const Object *ob_orig = DEG_get_original_object(ob); - /* FIXME(@campbellbarton): We should be able to use the CoW object, + /* FIXME(@ideasman42): We should be able to use the CoW object, * however the active bone isn't updated. Long term solution is an 'EditArmature' struct. - * for now we can draw from the original armature. See: T66773. */ + * for now we can draw from the original armature. See: #66773. */ // bArmature *arm = ob->data; bArmature *arm = static_cast(ob_orig->data); diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.cc b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc index f705bde6b54..256588e56f2 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_mesh.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc @@ -85,7 +85,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata) if ((flag & V3D_OVERLAY_EDIT_EDGES) == 0) { if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) { if ((v3d->shading.type < OB_SOLID) || (v3d->shading.flag & V3D_SHADING_XRAY)) { - /* Special case, when drawing wire, draw edges, see: T67637. */ + /* Special case, when drawing wire, draw edges, see: #67637. */ } else { pd->edit_mesh.do_edges = false; diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.cc b/source/blender/draw/engines/overlay/overlay_edit_uv.cc index 8b3c4e5d0ce..9e95b2eca05 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc @@ -414,7 +414,7 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) /* HACK: When editing objects that share the same mesh we should only draw the * first one in the order that is used during uv editing. We can only trust that the first object - * has the correct batches with the correct selection state. See T83187. */ + * has the correct batches with the correct selection state. See #83187. */ if ((pd->edit_uv.do_uv_overlay || pd->edit_uv.do_uv_shadow_overlay) && draw_ctx->obact->type == OB_MESH) { uint objects_len = 0; diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index e8300e81f2f..6f90645a0da 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -248,7 +248,7 @@ BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bo static bool overlay_object_is_edit_mode(const OVERLAY_PrivateData *pd, const Object *ob) { if (DRW_object_is_in_edit_mode(ob)) { - /* Also check for context mode as the object mode is not 100% reliable. (see T72490) */ + /* Also check for context mode as the object mode is not 100% reliable. (see #72490) */ switch (ob->type) { case OB_MESH: return pd->ctx_mode == CTX_MODE_EDIT_MESH; diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc index 8a4e8734ebe..88978750766 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.cc +++ b/source/blender/draw/engines/overlay/overlay_extra.cc @@ -645,7 +645,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) } else if (la->type == LA_SPOT) { /* Previous implementation was using the clip-end distance as cone size. - * We cannot do this anymore so we use a fixed size of 10. (see T72871) */ + * We cannot do this anymore so we use a fixed size of 10. (see #72871) */ const float3 scale_vec = {10.0f, 10.0f, 10.0f}; rescale_m4(instdata.mat, scale_vec); /* For cycles and EEVEE the spot attenuation is: diff --git a/source/blender/draw/engines/overlay/overlay_image.cc b/source/blender/draw/engines/overlay/overlay_image.cc index 7b99bd6bd18..622dc7339ca 100644 --- a/source/blender/draw/engines/overlay/overlay_image.cc +++ b/source/blender/draw/engines/overlay/overlay_image.cc @@ -375,7 +375,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob) { /* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead, - * see: T59347 */ + * see: #59347 */ int size[2] = {0}; if (ima != nullptr) { ImageUser iuser = *ob->iuser; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl index 1f6ff4e7d3a..a3d797a3664 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl @@ -9,7 +9,7 @@ void do_vertex(vec4 color, vec4 pos, float coord, vec2 offset) gl_Position = pos; /* Multiply offset by 2 because gl_Position range is [-1..1]. */ gl_Position.xy += offset * 2.0 * pos.w; - /* Correct but fails due to an AMD compiler bug, see: T62792. + /* Correct but fails due to an AMD compiler bug, see: #62792. * Do inline instead. */ #if 0 view_clipping_distances_set(gl_in[i]); @@ -62,7 +62,7 @@ void main() edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz; /* Due to an AMD glitch, this line was moved out of the `do_vertex` - * function (see T62792). */ + * function (see #62792). */ view_clipping_distances_set(gl_in[0]); do_vertex(geometry_in[0].finalColor_, pos0, half_size, edge_ofs.xy); do_vertex(geometry_in[0].finalColor_, pos0, -half_size, -edge_ofs.xy); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl index c9dc90e4113..140fc038cf6 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl @@ -22,7 +22,7 @@ void main() if (lineStyle == OVERLAY_UV_LINE_STYLE_OUTLINE) { #ifdef USE_EDGE_SELECT - /* TODO(@campbellbarton): The current wire-edit color contrast enough against the selection. + /* TODO(@ideasman42): The current wire-edit color contrast enough against the selection. * Look into changing the default theme color instead of reducing contrast with edge-select. */ inner_color = (geom_out.selectionFac != 0.0) ? colorEdgeSelect : (colorWireEdit * 0.5); #else diff --git a/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl index b401c3e7b2e..2b333696f94 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl @@ -81,7 +81,7 @@ void main() } else { dist = gl_FragCoord.z * 2.0 - 1.0; - /* Avoid fading in +Z direction in camera view (see T70193). */ + /* Avoid fading in +Z direction in camera view (see #70193). */ dist = flag_test(grid_flag, GRID_CAMERA) ? clamp(dist, 0.0, 1.0) : abs(dist); fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5); dist = 1.0; /* Avoid branch after. */ diff --git a/source/blender/draw/engines/overlay/shaders/overlay_image_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_image_vert.glsl index 45cddb3610d..be56c45dc9f 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_image_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_image_vert.glsl @@ -6,7 +6,7 @@ void main() { vec3 world_pos = point_object_to_world(pos); if (isCameraBackground) { - /* Model matrix converts to view position to avoid jittering (see T91398). */ + /* Model matrix converts to view position to avoid jittering (see #91398). */ gl_Position = point_view_to_ndc(world_pos); /* Camera background images are not really part of the 3D space. * It makes no sense to apply clipping on them. */ diff --git a/source/blender/draw/engines/select/select_draw_utils.c b/source/blender/draw/engines/select/select_draw_utils.c index 613b60f8829..03b189a3e5b 100644 --- a/source/blender/draw/engines/select/select_draw_utils.c +++ b/source/blender/draw/engines/select/select_draw_utils.c @@ -51,7 +51,7 @@ short select_id_get_object_select_mode(Scene *scene, Object *ob) * we need to be in SCE_SELECT_FACE mode so select_cache_init() correctly sets up * a shgroup with select_id_flat. * Note this is not working correctly for vertex-paint (yet), but has been discussed - * in T66645 and there is a solution by @mano-wii in P1032. + * in #66645 and there is a solution by @mano-wii in P1032. * So OB_MODE_VERTEX_PAINT is already included here [required for P1032 I guess]. */ Mesh *me_orig = DEG_get_original_object(ob)->data; if (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) { @@ -130,7 +130,7 @@ static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, } else { /* Note that `r_vert_offset` is calculated from `r_edge_offset`. - * Otherwise the first vertex is never selected, see: T53512. */ + * Otherwise the first vertex is never selected, see: #53512. */ *r_edge_offset = *r_face_offset; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl index 30daca6b7e3..d436707afc7 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl @@ -2,7 +2,7 @@ void main() { float depth = texture(depthBuffer, uvcoordsvar.xy).r; - /* Fix issues with Intel drivers (see T80023). */ + /* Fix issues with Intel drivers (see #80023). */ fragColor = vec4(0.0); /* Discard background pixels. */ if (depth == 1.0) { diff --git a/source/blender/draw/engines/workbench/workbench_shader_shared.h b/source/blender/draw/engines/workbench/workbench_shader_shared.h index d78e3408ccb..d7983e5eb80 100644 --- a/source/blender/draw/engines/workbench/workbench_shader_shared.h +++ b/source/blender/draw/engines/workbench/workbench_shader_shared.h @@ -59,6 +59,6 @@ struct ExtrudedFrustum { struct ShadowPassData { float4 far_plane; - float3 light_direction_ws; + packed_float3 light_direction_ws; int _padding; }; diff --git a/source/blender/draw/engines/workbench/workbench_shadow.c b/source/blender/draw/engines/workbench/workbench_shadow.c index 211c0e27418..655093a3fd4 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.c +++ b/source/blender/draw/engines/workbench/workbench_shadow.c @@ -319,7 +319,7 @@ void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const boo use_shadow_pass_technique = false; } - /* We cannot use Shadow Pass technique on non-manifold object (see T76168). */ + /* We cannot use Shadow Pass technique on non-manifold object (see #76168). */ if (use_shadow_pass_technique && !is_manifold && (wpd->cull_state != 0)) { use_shadow_pass_technique = false; } diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc index dff3314813c..ff50fd3732c 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.cc +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -259,17 +259,16 @@ void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw); GPU_shader_uniform_1b(shader, "force_fail_method", force_fail_method_); GPU_shader_uniform_3fv(shader, "shadow_direction", light_direction_); - GPU_uniformbuf_bind(extruded_frustum_, - GPU_shader_get_uniform_block(shader, "extruded_frustum")); - GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf")); + GPU_uniformbuf_bind(extruded_frustum_, GPU_shader_get_ubo_binding(shader, "extruded_frustum")); + GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo_binding(shader, "bounds_buf")); if (current_pass_type_ == ShadowPass::FORCED_FAIL) { - GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf")); + GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo_binding(shader, "visibility_buf")); } else { GPU_storagebuf_bind(pass_visibility_buf_, - GPU_shader_get_ssbo(shader, "pass_visibility_buf")); + GPU_shader_get_ssbo_binding(shader, "pass_visibility_buf")); GPU_storagebuf_bind(fail_visibility_buf_, - GPU_shader_get_ssbo(shader, "fail_visibility_buf")); + GPU_shader_get_ssbo_binding(shader, "fail_visibility_buf")); } GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT); GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1); @@ -439,7 +438,7 @@ void ShadowPass::object_sync(SceneState &scene_state, #endif /* Shadow pass technique needs object to be have all its surface opaque. */ - /* We cannot use the PASS technique on non-manifold object (see T76168). */ + /* We cannot use the PASS technique on non-manifold object (see #76168). */ bool force_fail_pass = has_transp_mat || (!is_manifold && (scene_state.cull_state != 0)); PassType fail_type = force_fail_pass ? FORCED_FAIL : FAIL; diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index 22ad08b1cb9..0633e8811bb 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -460,6 +460,13 @@ class StorageBuffer : public T, public detail::StorageCommon *static_cast(this) = other; return *this; } + + static void swap(StorageBuffer &a, StorageBuffer &b) + { + /* Swap content, but not `data_` pointers since they point to `this`. */ + SWAP(T, static_cast(a), static_cast(b)); + std::swap(a.ssbo_, b.ssbo_); + } }; /** \} */ @@ -1162,6 +1169,11 @@ template class SwapChain { } } + constexpr int64_t size() + { + return len; + } + T ¤t() { return chain_[0]; diff --git a/source/blender/draw/intern/draw_attributes.h b/source/blender/draw/intern/draw_attributes.h index 223c2a26c60..66320f1b500 100644 --- a/source/blender/draw/intern/draw_attributes.h +++ b/source/blender/draw/intern/draw_attributes.h @@ -47,7 +47,7 @@ typedef struct DRW_MeshCDMask { uint32_t tan_orco : 1; uint32_t sculpt_overlays : 1; /** - * Edit uv layer is from the base edit mesh as modifiers could remove it. (see T68857) + * Edit uv layer is from the base edit mesh as modifiers could remove it. (see #68857) */ uint32_t edit_uv : 1; } DRW_MeshCDMask; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index f1f62d8aee9..abe3283bab7 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -386,7 +386,7 @@ GPUBatch *DRW_cache_fullscreen_quad_get(void) attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); attr_id.uvs = GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_vertformat_alias_add(&format, "texCoord"); - GPU_vertformat_alias_add(&format, "orco"); /* Fix driver bug (see T70004) */ + GPU_vertformat_alias_add(&format, "orco"); /* Fix driver bug (see #70004) */ } GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.cc b/source/blender/draw/intern/draw_cache_impl_gpencil.cc index c51d408ea9c..5f61cc3f926 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc @@ -904,10 +904,10 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in /* Create the batches */ cache->edit_points_batch = GPU_batch_create(GPU_PRIM_POINTS, cache->vbo, nullptr); - GPU_batch_vertbuf_add(cache->edit_points_batch, cache->edit_vbo); + GPU_batch_vertbuf_add(cache->edit_points_batch, cache->edit_vbo, false); cache->edit_lines_batch = GPU_batch_create(GPU_PRIM_LINE_STRIP, cache->vbo, nullptr); - GPU_batch_vertbuf_add(cache->edit_lines_batch, cache->edit_vbo); + GPU_batch_vertbuf_add(cache->edit_lines_batch, cache->edit_vbo, false); } /* Curve Handles and Points for Editing. */ @@ -941,11 +941,11 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in cache->edit_curve_handles_batch = GPU_batch_create( GPU_PRIM_LINES, cache->edit_curve_vbo, nullptr); - GPU_batch_vertbuf_add(cache->edit_curve_handles_batch, cache->edit_curve_vbo); + GPU_batch_vertbuf_add(cache->edit_curve_handles_batch, cache->edit_curve_vbo, false); cache->edit_curve_points_batch = GPU_batch_create( GPU_PRIM_POINTS, cache->edit_curve_vbo, nullptr); - GPU_batch_vertbuf_add(cache->edit_curve_points_batch, cache->edit_curve_vbo); + GPU_batch_vertbuf_add(cache->edit_curve_points_batch, cache->edit_curve_vbo, false); } gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY; diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index bfeafdf7dcb..f8077882c12 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -369,7 +369,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) : CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2); - /* Only fallback to orco (below) when we have no UV layers, see: T56545 */ + /* Only fallback to orco (below) when we have no UV layers, see: #56545 */ if (layer == -1 && name[0] != '\0') { layer = CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2); } @@ -750,7 +750,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode) break; case BKE_MESH_BATCH_DIRTY_SELECT_PAINT: /* Paint mode selection flag is packed inside the nor attribute. - * Note that it can be slow if auto smooth is enabled. (see T63946) */ + * Note that it can be slow if auto smooth is enabled. (see #63946) */ FOREACH_MESH_BUFFER_CACHE (cache, mbc) { GPU_INDEXBUF_DISCARD_SAFE(mbc->buff.ibo.lines_paint_mask); GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.pos_nor); @@ -1315,7 +1315,7 @@ static void drw_mesh_batch_cache_check_available(struct TaskGraph *task_graph, M MeshBatchCache *cache = mesh_batch_cache_get(me); /* Make sure all requested batches have been setup. */ /* NOTE: The next line creates a different scheduling than during release builds what can lead to - * some issues (See T77867 where we needed to disable this function in order to debug what was + * some issues (See #77867 where we needed to disable this function in order to debug what was * happening in release builds). */ BLI_task_graph_work_and_wait(task_graph); for (int i = 0; i < MBC_BATCH_LEN; i++) { @@ -1941,7 +1941,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, /* Ensure that all requested batches have finished. * Ideally we want to remove this sync, but there are cases where this doesn't work. - * See T79038 for example. + * See #79038 for example. * * An idea to improve this is to separate the Object mode from the edit mode draw caches. And * based on the mode the correct one will be updated. Other option is to look into using diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 25ec4a578d5..0fe5eba26f4 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -1220,7 +1220,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, /* To avoid floating point precision issues when evaluating patches at patch boundaries, * ensure that all loops sharing a vertex use the same patch coordinate. This could cause - * the mesh to not be watertight, leading to shadowing artifacts (see T97877). */ + * the mesh to not be watertight, leading to shadowing artifacts (see #97877). */ blender::Vector first_loop_index(cache->num_subdiv_verts, -1); /* Save coordinates for corners, as attributes may vary for each loop connected to the same @@ -1350,7 +1350,7 @@ static void draw_subdiv_ubo_update_and_bind(const DRWSubdivCache *cache, GPU_uniformbuf_update(cache->ubo, &storage); - const int binding = GPU_shader_get_uniform_block_binding(shader, "shader_data"); + const int binding = GPU_shader_get_ubo_binding(shader, "shader_data"); GPU_uniformbuf_bind(cache->ubo, binding); } diff --git a/source/blender/draw/intern/draw_cache_impl_volume.cc b/source/blender/draw/intern/draw_cache_impl_volume.cc index dd89e84ed71..46bfefe64e3 100644 --- a/source/blender/draw/intern/draw_cache_impl_volume.cc +++ b/source/blender/draw/intern/draw_cache_impl_volume.cc @@ -197,7 +197,7 @@ static void drw_volume_wireframe_cb( GPU_PRIM_LINES, cache->face_wire.pos_nor_in_order, ibo, GPU_BATCH_OWNS_INDEX); } - GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wiredata, true); + GPU_batch_vertbuf_add(cache->face_wire.batch, vbo_wiredata, true); } GPUBatch *DRW_volume_batch_cache_get_wireframes_face(Volume *volume) diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h index 68260b1d057..6921afe83c1 100644 --- a/source/blender/draw/intern/draw_cache_inline.h +++ b/source/blender/draw/intern/draw_cache_inline.h @@ -71,7 +71,7 @@ BLI_INLINE void DRW_vbo_request(GPUBatch *batch, GPUVertBuf **vbo) } if (batch != NULL) { /* HACK we set VBO's that may not yet be valid. */ - GPU_batch_vertbuf_add(batch, *vbo); + GPU_batch_vertbuf_add(batch, *vbo, false); } } diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 775ee9f695b..86a0480b3f7 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -76,16 +76,16 @@ void PushConstant::execute(RecordingState &state) const } switch (type) { case PushConstant::Type::IntValue: - GPU_shader_uniform_vector_int(state.shader, location, comp_len, array_len, int4_value); + GPU_shader_uniform_int_ex(state.shader, location, comp_len, array_len, int4_value); break; case PushConstant::Type::IntReference: - GPU_shader_uniform_vector_int(state.shader, location, comp_len, array_len, int_ref); + GPU_shader_uniform_int_ex(state.shader, location, comp_len, array_len, int_ref); break; case PushConstant::Type::FloatValue: - GPU_shader_uniform_vector(state.shader, location, comp_len, array_len, float4_value); + GPU_shader_uniform_float_ex(state.shader, location, comp_len, array_len, float4_value); break; case PushConstant::Type::FloatReference: - GPU_shader_uniform_vector(state.shader, location, comp_len, array_len, float_ref); + GPU_shader_uniform_float_ex(state.shader, location, comp_len, array_len, float_ref); break; } } @@ -646,10 +646,10 @@ void DrawMultiBuf::bind(RecordingState &state, GPU_shader_uniform_1i(shader, "prototype_len", prototype_count_); GPU_shader_uniform_1i(shader, "visibility_word_per_draw", visibility_word_per_draw); GPU_shader_uniform_1i(shader, "view_shift", log2_ceil_u(view_len)); - GPU_storagebuf_bind(group_buf_, GPU_shader_get_ssbo(shader, "group_buf")); - GPU_storagebuf_bind(visibility_buf, GPU_shader_get_ssbo(shader, "visibility_buf")); - GPU_storagebuf_bind(prototype_buf_, GPU_shader_get_ssbo(shader, "prototype_buf")); - GPU_storagebuf_bind(command_buf_, GPU_shader_get_ssbo(shader, "command_buf")); + GPU_storagebuf_bind(group_buf_, GPU_shader_get_ssbo_binding(shader, "group_buf")); + GPU_storagebuf_bind(visibility_buf, GPU_shader_get_ssbo_binding(shader, "visibility_buf")); + GPU_storagebuf_bind(prototype_buf_, GPU_shader_get_ssbo_binding(shader, "prototype_buf")); + GPU_storagebuf_bind(command_buf_, GPU_shader_get_ssbo_binding(shader, "command_buf")); GPU_storagebuf_bind(resource_id_buf_, DRW_RESOURCE_ID_SLOT); GPU_compute_dispatch(shader, divide_ceil_u(prototype_count_, DRW_COMMAND_GROUP_SIZE), 1, 1); if (GPU_shader_draw_parameters_support() == false) { diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 45a72d67d31..2be32cc704c 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -393,7 +393,7 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip); if (gpu_material) { /* NOTE: This needs to happen before the drawcall to allow correct attribute extraction. - * (see T101896) */ + * (see #101896) */ DRW_shgroup_add_material_resources(shgrp, gpu_material); } /* TODO(fclem): Until we have a better way to cull the curves and render with orco, bypass @@ -412,7 +412,7 @@ void DRW_curves_update() if (!GPU_transform_feedback_support()) { /** * Workaround to transform feedback not working on mac. - * On some system it crashes (see T58489) and on some other it renders garbage (see T60171). + * On some system it crashes (see #58489) and on some other it renders garbage (see #60171). * * So instead of using transform feedback we render to a texture, * read back the result to system memory and re-upload as VBO data. diff --git a/source/blender/draw/intern/draw_debug.cc b/source/blender/draw/intern/draw_debug.cc index ca17aa1de82..4698d6eb5ff 100644 --- a/source/blender/draw/intern/draw_debug.cc +++ b/source/blender/draw/intern/draw_debug.cc @@ -523,19 +523,18 @@ void DebugDraw::display_lines() GPUBatch *batch = drw_cache_procedural_lines_get(); GPUShader *shader = DRW_shader_debug_draw_display_get(); GPU_batch_set_shader(batch, shader); - int slot = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_VERTS); GPU_shader_uniform_mat4(shader, "persmat", persmat.ptr()); if (gpu_draw_buf_used) { GPU_debug_group_begin("GPU"); - GPU_storagebuf_bind(gpu_draw_buf_, slot); + GPU_storagebuf_bind(gpu_draw_buf_, DRW_DEBUG_DRAW_SLOT); GPU_batch_draw_indirect(batch, gpu_draw_buf_, 0); GPU_storagebuf_unbind(gpu_draw_buf_); GPU_debug_group_end(); } GPU_debug_group_begin("CPU"); - GPU_storagebuf_bind(cpu_draw_buf_, slot); + GPU_storagebuf_bind(cpu_draw_buf_, DRW_DEBUG_DRAW_SLOT); GPU_batch_draw_indirect(batch, cpu_draw_buf_, 0); GPU_storagebuf_unbind(cpu_draw_buf_); GPU_debug_group_end(); @@ -556,21 +555,20 @@ void DebugDraw::display_prints() GPUBatch *batch = drw_cache_procedural_points_get(); GPUShader *shader = DRW_shader_debug_print_display_get(); GPU_batch_set_shader(batch, shader); - int slot = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT); float f_viewport[4]; GPU_viewport_size_get_f(f_viewport); GPU_shader_uniform_2fv(shader, "viewport_size", &f_viewport[2]); if (gpu_print_buf_used) { GPU_debug_group_begin("GPU"); - GPU_storagebuf_bind(gpu_print_buf_, slot); + GPU_storagebuf_bind(gpu_print_buf_, DRW_DEBUG_PRINT_SLOT); GPU_batch_draw_indirect(batch, gpu_print_buf_, 0); GPU_storagebuf_unbind(gpu_print_buf_); GPU_debug_group_end(); } GPU_debug_group_begin("CPU"); - GPU_storagebuf_bind(cpu_print_buf_, slot); + GPU_storagebuf_bind(cpu_print_buf_, DRW_DEBUG_PRINT_SLOT); GPU_batch_draw_indirect(batch, cpu_print_buf_, 0); GPU_storagebuf_unbind(cpu_print_buf_); GPU_debug_group_end(); diff --git a/source/blender/draw/intern/draw_hair.cc b/source/blender/draw/intern/draw_hair.cc index da04f199157..e8220346d25 100644 --- a/source/blender/draw/intern/draw_hair.cc +++ b/source/blender/draw/intern/draw_hair.cc @@ -295,7 +295,7 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object, DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip); if (gpu_material) { /* NOTE: This needs to happen before the drawcall to allow correct attribute extraction. - * (see T101896) */ + * (see #101896) */ DRW_shgroup_add_material_resources(shgrp, gpu_material); } /* TODO(fclem): Until we have a better way to cull the hair and render with orco, bypass @@ -311,7 +311,7 @@ void DRW_hair_update() if (!GPU_transform_feedback_support()) { /** * Workaround to transform feedback not working on mac. - * On some system it crashes (see T58489) and on some other it renders garbage (see T60171). + * On some system it crashes (see #58489) and on some other it renders garbage (see #60171). * * So instead of using transform feedback we render to a texture, * read back the result to system memory and re-upload as VBO data. diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index b44c1364af9..bf4efa30785 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -226,11 +226,11 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) GPU_batch_copy(batch, geom); if (inst_batch != NULL) { for (int i = 0; i < GPU_BATCH_INST_VBO_MAX_LEN && inst_batch->verts[i]; i++) { - GPU_batch_instbuf_add_ex(batch, inst_batch->verts[i], false); + GPU_batch_instbuf_add(batch, inst_batch->verts[i], false); } } else { - GPU_batch_instbuf_add_ex(batch, inst_buf, false); + GPU_batch_instbuf_add(batch, inst_buf, false); } /* Add reference to avoid comparing pointers (in DRW_temp_batch_request) that could * potentially be the same. This will delay the freeing of the GPUVertBuf itself. */ diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 289f4355a54..a8c5e696552 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1184,7 +1184,7 @@ static void drw_engines_enable_from_engine(const RenderEngineType *engine_type, case OB_WIRE: case OB_SOLID: if (U.experimental.enable_workbench_next && - strcmp(engine_type->idname, "BLENDER_WORKBENCH_NEXT") == 0) { + STREQ(engine_type->idname, "BLENDER_WORKBENCH_NEXT")) { use_drw_engine(DRW_engine_viewport_workbench_next_type.draw_engine); break; } @@ -1763,7 +1763,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_engines_draw_scene(); - /* Fix 3D view "lagging" on APPLE and WIN32+NVIDIA. (See T56996, T61474) */ + /* Fix 3D view "lagging" on APPLE and WIN32+NVIDIA. (See #56996, #61474) */ if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) { GPU_flush(); } @@ -2138,7 +2138,7 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type, /* The use of custom pipeline in other thread using the same * resources as the main thread (viewport) may lead to data * races and undefined behavior on certain drivers. Using - * GPU_finish to sync seems to fix the issue. (see T62997) */ + * GPU_finish to sync seems to fix the issue. (see #62997) */ eGPUBackendType type = GPU_backend_get_type(); if (type == GPU_BACKEND_OPENGL) { GPU_finish(); @@ -2251,7 +2251,7 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph, drw_engines_draw_scene(); - /* Fix 3D view being "laggy" on MACOS and MS-Windows+NVIDIA. (See T56996, T61474) */ + /* Fix 3D view being "laggy" on MACOS and MS-Windows+NVIDIA. (See #56996, #61474) */ if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) { GPU_flush(); } @@ -2780,7 +2780,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons drw_engines_cache_finish(); drw_task_graph_deinit(); -#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug. (See T69377) */ +#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug. (See #69377) */ DRW_render_instance_buffer_finish(); #else DST.buffer_finish_called = true; @@ -3072,7 +3072,7 @@ void DRW_engines_free(void) if (DST.gl_context == NULL) { /* Nothing has been setup. Nothing to clear. * Otherwise, DRW_opengl_context_enable can - * create a context in background mode. (see T62355) */ + * create a context in background mode. (see #62355) */ return; } diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc index c222d52141c..f34650255a5 100644 --- a/source/blender/draw/intern/draw_manager.cc +++ b/source/blender/draw/intern/draw_manager.cc @@ -43,9 +43,15 @@ void Manager::begin_sync() #ifdef DEBUG /* Detect uninitialized data. */ - memset(matrix_buf.current().data(), 0xF0, resource_len_ * sizeof(*matrix_buf.current().data())); - memset(bounds_buf.current().data(), 0xF0, resource_len_ * sizeof(*bounds_buf.current().data())); - memset(infos_buf.current().data(), 0xF0, resource_len_ * sizeof(*infos_buf.current().data())); + memset(matrix_buf.current().data(), + 0xF0, + matrix_buf.current().size() * sizeof(*matrix_buf.current().data())); + memset(bounds_buf.current().data(), + 0xF0, + matrix_buf.current().size() * sizeof(*bounds_buf.current().data())); + memset(infos_buf.current().data(), + 0xF0, + matrix_buf.current().size() * sizeof(*infos_buf.current().data())); #endif resource_len_ = 0; attribute_len_ = 0; @@ -108,9 +114,9 @@ void Manager::end_sync() GPUShader *shader = DRW_shader_draw_resource_finalize_get(); GPU_shader_bind(shader); GPU_shader_uniform_1i(shader, "resource_len", resource_len_); - GPU_storagebuf_bind(matrix_buf.current(), GPU_shader_get_ssbo(shader, "matrix_buf")); - GPU_storagebuf_bind(bounds_buf.current(), GPU_shader_get_ssbo(shader, "bounds_buf")); - GPU_storagebuf_bind(infos_buf.current(), GPU_shader_get_ssbo(shader, "infos_buf")); + GPU_storagebuf_bind(matrix_buf.current(), GPU_shader_get_ssbo_binding(shader, "matrix_buf")); + GPU_storagebuf_bind(bounds_buf.current(), GPU_shader_get_ssbo_binding(shader, "bounds_buf")); + GPU_storagebuf_bind(infos_buf.current(), GPU_shader_get_ssbo_binding(shader, "infos_buf")); GPU_compute_dispatch(shader, thread_groups, 1, 1); GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index de78c8216de..546ccbf7ef8 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -256,7 +256,7 @@ void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup, eGPUSamplerState sampler_state) { BLI_assert(tex != nullptr); - int loc = GPU_shader_get_texture_binding(shgroup->shader, name); + int loc = GPU_shader_get_sampler_binding(shgroup->shader, name); drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_TEXTURE, tex, sampler_state, 0, 1); } @@ -271,7 +271,7 @@ void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup, eGPUSamplerState sampler_state) { BLI_assert(tex != nullptr); - int loc = GPU_shader_get_texture_binding(shgroup->shader, name); + int loc = GPU_shader_get_sampler_binding(shgroup->shader, name); drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_TEXTURE_REF, tex, sampler_state, 0, 1); } @@ -283,14 +283,14 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex) { BLI_assert(tex != nullptr); - int loc = GPU_shader_get_texture_binding(shgroup->shader, name); + int loc = GPU_shader_get_sampler_binding(shgroup->shader, name); drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE, tex, GPU_SAMPLER_DEFAULT, 0, 1); } void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex) { BLI_assert(tex != nullptr); - int loc = GPU_shader_get_texture_binding(shgroup->shader, name); + int loc = GPU_shader_get_sampler_binding(shgroup->shader, name); drw_shgroup_uniform_create_ex( shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, GPU_SAMPLER_DEFAULT, 0, 1); } @@ -300,7 +300,7 @@ void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup, const GPUUniformBuf *ubo DRW_DEBUG_FILE_LINE_ARGS) { BLI_assert(ubo != nullptr); - int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name); + int loc = GPU_shader_get_ubo_binding(shgroup->shader, name); if (loc == -1) { #ifdef DRW_UNUSED_RESOURCE_TRACKING printf("%s:%d: Unable to locate binding of shader uniform buffer object: %s.\n", @@ -321,7 +321,7 @@ void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup, GPUUniformBuf **ubo DRW_DEBUG_FILE_LINE_ARGS) { BLI_assert(ubo != nullptr); - int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name); + int loc = GPU_shader_get_ubo_binding(shgroup->shader, name); if (loc == -1) { #ifdef DRW_UNUSED_RESOURCE_TRACKING printf("%s:%d: Unable to locate binding of shader uniform buffer object: %s.\n", @@ -344,7 +344,7 @@ void DRW_shgroup_storage_block_ex(DRWShadingGroup *shgroup, { BLI_assert(ssbo != nullptr); /* TODO(@fclem): Fix naming inconsistency. */ - int loc = GPU_shader_get_ssbo(shgroup->shader, name); + int loc = GPU_shader_get_ssbo_binding(shgroup->shader, name); if (loc == -1) { #ifdef DRW_UNUSED_RESOURCE_TRACKING printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n", @@ -367,7 +367,7 @@ void DRW_shgroup_storage_block_ref_ex(DRWShadingGroup *shgroup, { BLI_assert(ssbo != nullptr); /* TODO(@fclem): Fix naming inconsistency. */ - int loc = GPU_shader_get_ssbo(shgroup->shader, name); + int loc = GPU_shader_get_ssbo_binding(shgroup->shader, name); if (loc == -1) { #ifdef DRW_UNUSED_RESOURCE_TRACKING printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n", @@ -539,7 +539,7 @@ void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup, const char *name, GPUVertBuf *vertex_buffer DRW_DEBUG_FILE_LINE_ARGS) { - int location = GPU_shader_get_ssbo(shgroup->shader, name); + int location = GPU_shader_get_ssbo_binding(shgroup->shader, name); if (location == -1) { #ifdef DRW_UNUSED_RESOURCE_TRACKING printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n", @@ -564,7 +564,7 @@ void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup, const char *name, GPUVertBuf **vertex_buffer DRW_DEBUG_FILE_LINE_ARGS) { - int location = GPU_shader_get_ssbo(shgroup->shader, name); + int location = GPU_shader_get_ssbo_binding(shgroup->shader, name); if (location == -1) { #ifdef DRW_UNUSED_RESOURCE_TRACKING printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n", @@ -589,7 +589,7 @@ void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup, const char *name, GPUVertBuf *vertex_buffer) { - int location = GPU_shader_get_texture_binding(shgroup->shader, name); + int location = GPU_shader_get_sampler_binding(shgroup->shader, name); if (location == -1) { return; } @@ -606,7 +606,7 @@ void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUVertBuf **vertex_buffer) { - int location = GPU_shader_get_texture_binding(shgroup->shader, name); + int location = GPU_shader_get_sampler_binding(shgroup->shader, name); if (location == -1) { return; } @@ -698,7 +698,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob) drw_call_calc_orco(ob, ob_infos->orcotexfac); /* Random float value. */ uint random = (DST.dupli_source) ? - DST.dupli_source->random_id : + DST.dupli_source->random_id : /* TODO(fclem): this is rather costly to do at runtime. Maybe we can * put it in ob->runtime and make depsgraph ensure it is up to date. */ BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0); @@ -731,7 +731,7 @@ static void drw_call_culling_init(DRWCullingState *cull, Object *ob) mul_m4_v3(ob->object_to_world, cull->bsphere.center); cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner); - /* Bypass test for very large objects (see T67319). */ + /* Bypass test for very large objects (see #67319). */ if (UNLIKELY(cull->bsphere.radius > 1e12)) { cull->bsphere.radius = -1.0f; } @@ -1719,36 +1719,6 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) 1); } -#ifdef DEBUG - /* TODO(Metal): Support Shader debug print. - * This is not currently supported by Metal Backend. */ - if (GPU_backend_get_type() != GPU_BACKEND_METAL) { - int debug_print_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT); - if (debug_print_location != -1) { - GPUStorageBuf *buf = drw_debug_gpu_print_buf_get(); - drw_shgroup_uniform_create_ex(shgroup, - debug_print_location, - DRW_UNIFORM_STORAGE_BLOCK, - buf, - GPU_SAMPLER_DEFAULT, - 0, - 1); -# ifndef DISABLE_DEBUG_SHADER_PRINT_BARRIER - /* Add a barrier to allow multiple shader writing to the same buffer. */ - DRW_shgroup_barrier(shgroup, GPU_BARRIER_SHADER_STORAGE); -# endif - } - - int debug_draw_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_VERTS); - if (debug_draw_location != -1) { - GPUStorageBuf *buf = drw_debug_gpu_draw_buf_get(); - drw_shgroup_uniform_create_ex( - shgroup, debug_draw_location, DRW_UNIFORM_STORAGE_BLOCK, buf, GPU_SAMPLER_DEFAULT, 0, 1); - /* NOTE(fclem): No barrier as ordering is not important. */ - } - } -#endif - /* Not supported. */ BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV) == -1); BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW) == -1); @@ -1850,15 +1820,14 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *mater const GPUUniformAttrList *uattrs = GPU_material_uniform_attributes(material); if (uattrs != nullptr) { - int loc = GPU_shader_get_uniform_block_binding(grp->shader, GPU_ATTRIBUTE_UBO_BLOCK_NAME); + int loc = GPU_shader_get_ubo_binding(grp->shader, GPU_ATTRIBUTE_UBO_BLOCK_NAME); drw_shgroup_uniform_create_ex( grp, loc, DRW_UNIFORM_BLOCK_OBATTRS, uattrs, GPU_SAMPLER_DEFAULT, 0, 1); grp->uniform_attrs = uattrs; } if (GPU_material_layer_attributes(material) != nullptr) { - int loc = GPU_shader_get_uniform_block_binding(grp->shader, - GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME); + int loc = GPU_shader_get_ubo_binding(grp->shader, GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME); drw_shgroup_uniform_create_ex( grp, loc, DRW_UNIFORM_BLOCK_VLATTRS, nullptr, GPU_SAMPLER_DEFAULT, 0, 1); } @@ -2511,7 +2480,7 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass) /* To be sorted a shgroup needs to have at least one draw command. */ /* FIXME(fclem): In some case, we can still have empty shading group to sort. However their * final order is not well defined. - * (see T76730 & D7729). */ + * (see #76730 & D7729). */ // BLI_assert(handle != 0); DRWObjectMatrix *obmats = static_cast( diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index b68a1976f80..4139ffcb261 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -522,10 +522,10 @@ BLI_INLINE void draw_legacy_matrix_update(DRWShadingGroup *shgroup, /* Still supported for compatibility with gpu_shader_* but should be forbidden. */ DRWObjectMatrix *ob_mats = DRW_memblock_elem_from_handle(DST.vmempool->obmats, handle); if (obmat_loc != -1) { - GPU_shader_uniform_vector(shgroup->shader, obmat_loc, 16, 1, (float *)ob_mats->model); + GPU_shader_uniform_float_ex(shgroup->shader, obmat_loc, 16, 1, (float *)ob_mats->model); } if (obinv_loc != -1) { - GPU_shader_uniform_vector(shgroup->shader, obinv_loc, 16, 1, (float *)ob_mats->modelinverse); + GPU_shader_uniform_float_ex(shgroup->shader, obinv_loc, 16, 1, (float *)ob_mats->modelinverse); } } @@ -549,7 +549,7 @@ BLI_INLINE void draw_geometry_execute(DRWShadingGroup *shgroup, if (baseinst_loc != -1) { /* Fallback when ARB_shader_draw_parameters is not supported. */ - GPU_shader_uniform_vector_int(shgroup->shader, baseinst_loc, 1, 1, (int *)&inst_first); + GPU_shader_uniform_int_ex(shgroup->shader, baseinst_loc, 1, 1, (int *)&inst_first); /* Avoids VAO reconfiguration on older hardware. (see GPU_batch_draw_advanced) */ inst_first = 0; } @@ -615,7 +615,7 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, memcpy(&mat4_stack[array_index], uni->fvalue, sizeof(float) * uni->length); /* Flush array data to shader. */ if (array_index <= 0) { - GPU_shader_uniform_vector(shgroup->shader, uni->location, 16, 1, mat4_stack); + GPU_shader_uniform_float_ex(shgroup->shader, uni->location, 16, 1, mat4_stack); array_uniform_loc = -1; } continue; @@ -626,23 +626,23 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, case DRW_UNIFORM_INT_COPY: BLI_assert(uni->arraysize == 1); if (uni->arraysize == 1) { - GPU_shader_uniform_vector_int( + GPU_shader_uniform_int_ex( shgroup->shader, uni->location, uni->length, uni->arraysize, uni->ivalue); } break; case DRW_UNIFORM_INT: - GPU_shader_uniform_vector_int( + GPU_shader_uniform_int_ex( shgroup->shader, uni->location, uni->length, uni->arraysize, uni->pvalue); break; case DRW_UNIFORM_FLOAT_COPY: BLI_assert(uni->arraysize == 1); if (uni->arraysize == 1) { - GPU_shader_uniform_vector( + GPU_shader_uniform_float_ex( shgroup->shader, uni->location, uni->length, uni->arraysize, uni->fvalue); } break; case DRW_UNIFORM_FLOAT: - GPU_shader_uniform_vector( + GPU_shader_uniform_float_ex( shgroup->shader, uni->location, uni->length, uni->arraysize, uni->pvalue); break; case DRW_UNIFORM_TEXTURE: @@ -687,10 +687,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, state->vlattrs_loc = uni->location; GPU_uniformbuf_bind(drw_ensure_layer_attribute_buffer(), uni->location); break; - case DRW_UNIFORM_RESOURCE_CHUNK: + case DRW_UNIFORM_RESOURCE_CHUNK: { state->chunkid_loc = uni->location; - GPU_shader_uniform_int(shgroup->shader, uni->location, 0); + int zero = 0; + GPU_shader_uniform_int_ex(shgroup->shader, uni->location, 1, 1, &zero); break; + } case DRW_UNIFORM_RESOURCE_ID: state->resourceid_loc = uni->location; break; @@ -807,7 +809,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa int chunk = DRW_handle_chunk_get(handle); if (state->resource_chunk != chunk) { if (state->chunkid_loc != -1) { - GPU_shader_uniform_int(DST.shader, state->chunkid_loc, chunk); + GPU_shader_uniform_int_ex(DST.shader, state->chunkid_loc, 1, 1, &chunk); } if (state->obmats_loc != -1) { GPU_uniformbuf_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]); @@ -827,7 +829,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa if (state->resourceid_loc != -1) { int id = DRW_handle_id_get(handle); if (state->resource_id != id) { - GPU_shader_uniform_int(DST.shader, state->resourceid_loc, id); + GPU_shader_uniform_int_ex(DST.shader, state->resourceid_loc, 1, 1, &id); state->resource_id = id; } } @@ -1218,7 +1220,7 @@ static void drw_draw_pass_ex(DRWPass *pass, DST.batch = NULL; } - /* Fix T67342 for some reason. AMD Pro driver bug. */ + /* Fix #67342 for some reason. AMD Pro driver bug. */ if ((DST.state & DRW_STATE_BLEND_CUSTOM) != 0 && GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) { drw_state_set(DST.state & ~DRW_STATE_BLEND_CUSTOM); diff --git a/source/blender/draw/intern/draw_manager_text.cc b/source/blender/draw/intern/draw_manager_text.cc index 1244c46e166..c61ff7d4beb 100644 --- a/source/blender/draw/intern/draw_manager_text.cc +++ b/source/blender/draw/intern/draw_manager_text.cc @@ -216,7 +216,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, const UnitSettings *unit) { /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square, - * etc.). See bug T36090. + * etc.). See bug #36090. */ DRWTextStore *dt = DRW_text_cache_ensure(); const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE; diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 8fc8298491e..d05564c415a 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -861,42 +861,42 @@ template inline int PassBase::push_constant_offset(const char *name) template inline void PassBase::bind_ssbo(const char *name, GPUStorageBuf *buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ssbo(const char *name, GPUUniformBuf *buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ssbo(const char *name, GPUUniformBuf **buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ssbo(const char *name, GPUVertBuf *buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ssbo(const char *name, GPUVertBuf **buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ssbo(const char *name, GPUIndexBuf *buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ssbo(const char *name, GPUIndexBuf **buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ubo(const char *name, GPUUniformBuf *buffer) { - this->bind_ubo(GPU_shader_get_uniform_block_binding(shader_, name), buffer); + this->bind_ubo(GPU_shader_get_ubo_binding(shader_, name), buffer); } template @@ -904,22 +904,22 @@ inline void PassBase::bind_texture(const char *name, GPUTexture *texture, eGPUSamplerState state) { - this->bind_texture(GPU_shader_get_texture_binding(shader_, name), texture, state); + this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), texture, state); } template inline void PassBase::bind_texture(const char *name, GPUVertBuf *buffer) { - this->bind_texture(GPU_shader_get_texture_binding(shader_, name), buffer); + this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), buffer); } template inline void PassBase::bind_texture(const char *name, GPUVertBuf **buffer) { - this->bind_texture(GPU_shader_get_texture_binding(shader_, name), buffer); + this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), buffer); } template inline void PassBase::bind_image(const char *name, GPUTexture *image) { - this->bind_image(GPU_shader_get_texture_binding(shader_, name), image); + this->bind_image(GPU_shader_get_sampler_binding(shader_, name), image); } template inline void PassBase::bind_ssbo(int slot, GPUStorageBuf *buffer) @@ -991,12 +991,12 @@ template inline void PassBase::bind_image(int slot, GPUTexture *imag template inline void PassBase::bind_ssbo(const char *name, GPUStorageBuf **buffer) { - this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); + this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer); } template inline void PassBase::bind_ubo(const char *name, GPUUniformBuf **buffer) { - this->bind_ubo(GPU_shader_get_uniform_block_binding(shader_, name), buffer); + this->bind_ubo(GPU_shader_get_ubo_binding(shader_, name), buffer); } template @@ -1004,12 +1004,12 @@ inline void PassBase::bind_texture(const char *name, GPUTexture **texture, eGPUSamplerState state) { - this->bind_texture(GPU_shader_get_texture_binding(shader_, name), texture, state); + this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), texture, state); } template inline void PassBase::bind_image(const char *name, GPUTexture **image) { - this->bind_image(GPU_shader_get_texture_binding(shader_, name), image); + this->bind_image(GPU_shader_get_sampler_binding(shader_, name), image); } template inline void PassBase::bind_ssbo(int slot, GPUStorageBuf **buffer) diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 04d985be71e..84dd9e1f46b 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -1303,10 +1303,10 @@ struct PBVHBatches { int vbo_i = get_vbo_index(vbo); batch.vbos.append(vbo_i); - GPU_batch_vertbuf_add_ex(batch.tris, vbo->vert_buf, false); + GPU_batch_vertbuf_add(batch.tris, vbo->vert_buf, false); if (batch.lines) { - GPU_batch_vertbuf_add_ex(batch.lines, vbo->vert_buf, false); + GPU_batch_vertbuf_add(batch.lines, vbo->vert_buf, false); } } diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 670b0c5ecf5..46fd82a239e 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -244,7 +244,7 @@ void View::compute_procedural_bounds() GPUShader *shader = DRW_shader_draw_view_finalize_get(); GPU_shader_bind(shader); - GPU_uniformbuf_bind_as_ssbo(culling_, GPU_shader_get_ssbo(shader, "view_culling_buf")); + GPU_uniformbuf_bind_as_ssbo(culling_, GPU_shader_get_ssbo_binding(shader, "view_culling_buf")); GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT); GPU_compute_dispatch(shader, 1, 1, 1); GPU_memory_barrier(GPU_BARRIER_UNIFORM); @@ -289,8 +289,8 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d GPU_shader_uniform_1i(shader, "resource_len", resource_len); GPU_shader_uniform_1i(shader, "view_len", view_len_); GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw); - GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf")); - GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf")); + GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo_binding(shader, "bounds_buf")); + GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo_binding(shader, "visibility_buf")); GPU_uniformbuf_bind(frozen_ ? data_freeze_ : data_, DRW_VIEW_UBO_SLOT); GPU_uniformbuf_bind(frozen_ ? culling_freeze_ : culling_, DRW_VIEW_CULLING_UBO_SLOT); GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc index aea1aacf5ea..4360fd16b9d 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc @@ -60,15 +60,8 @@ static void extract_edge_fac_init(const MeshRenderData *mr, if (mr->extract_type == MR_EXTRACT_MESH) { data->edge_loop_count = MEM_cnew_array(mr->edge_len, __func__); - - /* HACK(@fclem): Detecting the need for edge render. - * We could have a flag in the mesh instead or check the modifier stack. */ - const MEdge *med = mr->medge; - for (int e_index = 0; e_index < mr->edge_len; e_index++, med++) { - if ((med->flag & ME_EDGEDRAW) == 0) { - data->use_edge_render = true; - break; - } + if (!mr->me->runtime->subsurf_optimal_display_edges.is_empty()) { + data->use_edge_render = true; } } else { @@ -109,6 +102,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr, void *_data) { MeshExtract_EdgeFac_Data *data = static_cast(_data); + const BitVector<> &optimal_display_edges = mr->me->runtime->subsurf_optimal_display_edges; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; @@ -116,8 +110,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr, const MLoop *ml = &mloop[ml_index]; if (data->use_edge_render) { - const MEdge *med = &mr->medge[ml->e]; - data->vbo_data[ml_index] = (med->flag & ME_EDGEDRAW) ? 255 : 0; + data->vbo_data[ml_index] = optimal_display_edges[ml->e] ? 255 : 0; } else { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc index c6ba9283084..d27af95c190 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc @@ -44,7 +44,7 @@ static void mesh_render_data_edge_flag(const MeshRenderData *mr, } /* Use active edge color for active face edges because - * specular highlights make it hard to see T55456#510873. + * specular highlights make it hard to see #55456#510873. * * This isn't ideal since it can't be used when mixing edge/face modes * but it's still better than not being able to see the active face. */ diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc index b295a314883..174223221fa 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc @@ -229,7 +229,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi * the data for the mesh when switching to the `UV Editing` workspace, and therefore the position * buffer might not be created yet. In this case, create a buffer it locally, the subdivision * data should already be evaluated if we are here. This can happen if the subsurf modifier is - * only enabled in edit-mode. See T96338. */ + * only enabled in edit-mode. See #96338. */ if (!pos_nor) { const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom; pos_nor = GPU_vertbuf_calloc(); @@ -245,7 +245,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_MESH) ? &mr->me->ldata : &mr->bm->ldata; uint32_t uv_layers = cache->cd_used.uv; - /* HACK to fix T68857 */ + /* HACK to fix #68857 */ if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) { int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2); if (layer != -1) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc index bd1c98b033f..971fead52cf 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc @@ -46,7 +46,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, int tan_len = 0; - /* FIXME(T91838): This is to avoid a crash when orco tangent was requested but there are valid + /* FIXME(#91838): This is to avoid a crash when orco tangent was requested but there are valid * uv layers. It would be better to fix the root cause. */ if (tan_layers == 0 && use_orco_tan && CustomData_get_layer_index(cd_ldata, CD_PROP_FLOAT2) != -1) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc index 2af8fa40844..bc73c59f556 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc @@ -28,7 +28,7 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format, GPU_vertformat_deinterleave(format); uint32_t uv_layers = cache->cd_used.uv; - /* HACK to fix T68857 */ + /* HACK to fix #68857 */ if (extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) { int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2); if (layer != -1) { diff --git a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl index 5b79ce71739..bb55035f9e6 100644 --- a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl +++ b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl @@ -123,7 +123,7 @@ bool gpencil_is_stroke_vertex() * * * WARNING: Max attribute count is actually 14 because OSX OpenGL implementation - * considers gl_VertexID and gl_InstanceID as vertex attribute. (see T74536) + * considers gl_VertexID and gl_InstanceID as vertex attribute. (see #74536) */ vec4 gpencil_vertex(vec4 viewport_size, gpMaterialFlag material_flags, diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index 0efaad47afb..4fea4f77990 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -190,7 +190,7 @@ void hair_get_center_pos_tan_binor_time(bool is_persp, # if defined(OS_MAC) && defined(GPU_OPENGL) /* Generate a dummy read to avoid the driver bug with shaders having no - * vertex reads on macOS (T60171) */ + * vertex reads on macOS (#60171) */ wpos.y += dummy * 0.0; # endif diff --git a/source/blender/draw/intern/shaders/common_math_lib.glsl b/source/blender/draw/intern/shaders/common_math_lib.glsl index 6011f3398a6..59eedee7c87 100644 --- a/source/blender/draw/intern/shaders/common_math_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_lib.glsl @@ -109,7 +109,7 @@ vec3 sqr(vec3 a) { return a * a; } vec4 sqr(vec4 a) { return a * a; } /* Use manual powers for fixed powers. pow() can have unpredictable results on some implementations. - * (see T87369, T87541) */ + * (see #87369, #87541) */ float pow6(float x) { return sqr(sqr(x) * x); } float pow8(float x) { return sqr(sqr(sqr(x))); } diff --git a/source/blender/draw/intern/shaders/draw_debug_info.hh b/source/blender/draw/intern/shaders/draw_debug_info.hh index 4b5590824ba..e2dc2d0208e 100644 --- a/source/blender/draw/intern/shaders/draw_debug_info.hh +++ b/source/blender/draw/intern/shaders/draw_debug_info.hh @@ -18,7 +18,7 @@ GPU_SHADER_INTERFACE_INFO(draw_debug_print_display_iface, "").flat(Type::UINT, " GPU_SHADER_CREATE_INFO(draw_debug_print_display) .do_static_compilation(true) .typedef_source("draw_shader_shared.h") - .storage_buf(7, Qualifier::READ, "uint", "drw_debug_print_buf[]") + .storage_buf(DRW_DEBUG_PRINT_SLOT, Qualifier::READ, "uint", "drw_debug_print_buf[]") .vertex_out(draw_debug_print_display_iface) .fragment_out(0, Type::VEC4, "out_color") .push_constant(Type::VEC2, "viewport_size") @@ -46,7 +46,7 @@ GPU_SHADER_INTERFACE_INFO(draw_debug_draw_display_iface, "interp").flat(Type::VE GPU_SHADER_CREATE_INFO(draw_debug_draw_display) .do_static_compilation(true) .typedef_source("draw_shader_shared.h") - .storage_buf(6, Qualifier::READ, "DRWDebugVert", "drw_debug_verts_buf[]") + .storage_buf(DRW_DEBUG_DRAW_SLOT, Qualifier::READ, "DRWDebugVert", "drw_debug_verts_buf[]") .vertex_out(draw_debug_draw_display_iface) .fragment_out(0, Type::VEC4, "out_color") .push_constant(Type::MAT4, "persmat") diff --git a/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl b/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl index 511d4e49651..b70cacbc55e 100644 --- a/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl @@ -46,7 +46,7 @@ void main() -bounds_buf[resource_id].bounding_corners[1].xyz; } - /* TODO: Bypass test for very large objects (see T67319). */ + /* TODO: Bypass test for very large objects (see #67319). */ if (bounds_buf[resource_id].bounding_sphere.w > 1e12) { bounds_buf[resource_id].bounding_sphere.w = -1.0; } diff --git a/source/blender/draw/tests/eevee_test.cc b/source/blender/draw/tests/eevee_test.cc new file mode 100644 index 00000000000..5ab7178803e --- /dev/null +++ b/source/blender/draw/tests/eevee_test.cc @@ -0,0 +1,1149 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include "testing/testing.h" + +#include "BKE_context.h" +#include "BKE_idtype.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_object.h" +#include "DEG_depsgraph.h" +#include "RNA_define.h" + +#include "GPU_batch.h" +#include "draw_shader.h" +#include "draw_testing.hh" +#include "engines/eevee_next/eevee_instance.hh" + +namespace blender::draw { + +using namespace blender::eevee; + +/* Replace with template version that is not GPU only. */ +using ShadowPageCacheBuf = draw::StorageArrayBuffer; +using ShadowTileDataBuf = draw::StorageArrayBuffer; + +static void test_eevee_shadow_shift_clear() +{ + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + + int tiles_index = 1; + int tile_lod0 = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 5; + int tile_lod1 = tile_lod0 + square_i(SHADOW_TILEMAP_RES); + + { + ShadowTileMapData tilemap = {}; + tilemap.tiles_index = tiles_index * SHADOW_TILEDATA_PER_TILEMAP; + tilemap.grid_shift = int2(SHADOW_TILEMAP_RES); + tilemap.projection_type = SHADOW_PROJECTION_CUBEFACE; + + tilemaps_data.append(tilemap); + + tilemaps_data.push_update(); + } + { + ShadowTileData tile; + + tile.page = uint2(1, 2); + tile.is_used = true; + tile.do_update = true; + tiles_data[tile_lod0] = shadow_tile_pack(tile); + + tile.page = uint2(3, 4); + tile.is_used = false; + tile.do_update = false; + tiles_data[tile_lod1] = shadow_tile_pack(tile); + + tiles_data.push_update(); + } + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_tilemap_init"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.dispatch(int3(1, 1, tilemaps_data.size())); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + tilemaps_data.read(); + tiles_data.read(); + + EXPECT_EQ(tilemaps_data[0].grid_offset, int2(0)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_lod0]).page, uint2(1, 2)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_lod0]).is_used, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_lod0]).do_update, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_lod1]).page, uint2(3, 4)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_lod1]).is_used, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_lod1]).do_update, true); + + GPU_shader_free(sh); + DRW_shaders_free(); +} +DRAW_TEST(eevee_shadow_shift_clear) + +static void test_eevee_shadow_shift() +{ + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + + { + ShadowTileMapData tilemap = {}; + tilemap.tiles_index = 0; + tilemap.clip_data_index = 0; + tilemap.grid_shift = int2(-1, 2); + tilemap.projection_type = SHADOW_PROJECTION_CLIPMAP; + + tilemaps_data.append(tilemap); + + tilemaps_data.push_update(); + } + { + + ShadowTileData tile = shadow_tile_unpack(ShadowTileDataPacked(SHADOW_NO_DATA)); + + for (auto x : IndexRange(SHADOW_TILEMAP_RES)) { + for (auto y : IndexRange(SHADOW_TILEMAP_RES)) { + tile.is_allocated = true; + tile.is_rendered = true; + tile.do_update = true; + tile.page = uint2(x, y); + tiles_data[x + y * SHADOW_TILEMAP_RES] = shadow_tile_pack(tile); + } + } + + tiles_data.push_update(); + } + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_tilemap_init"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.dispatch(int3(1, 1, tilemaps_data.size())); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + tilemaps_data.read(); + tiles_data.read(); + + EXPECT_EQ(tilemaps_data[0].grid_offset, int2(0)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0]).page, uint2(SHADOW_TILEMAP_RES - 1, 2)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0]).do_update, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0]).is_rendered, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0]).is_allocated, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1]).page, uint2(0, 2)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1]).do_update, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1]).is_rendered, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1]).is_allocated, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0 + SHADOW_TILEMAP_RES * 2]).page, + uint2(SHADOW_TILEMAP_RES - 1, 4)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0 + SHADOW_TILEMAP_RES * 2]).do_update, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0 + SHADOW_TILEMAP_RES * 2]).is_rendered, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[0 + SHADOW_TILEMAP_RES * 2]).is_allocated, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1 + SHADOW_TILEMAP_RES * 2]).page, uint2(0, 4)); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1 + SHADOW_TILEMAP_RES * 2]).do_update, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1 + SHADOW_TILEMAP_RES * 2]).is_rendered, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[1 + SHADOW_TILEMAP_RES * 2]).is_allocated, true); + + GPU_shader_free(sh); + DRW_shaders_free(); +} +DRAW_TEST(eevee_shadow_shift) + +static void test_eevee_shadow_tag_update() +{ + using namespace blender::math; + StorageVectorBuffer past_casters_updated = {"PastCastersUpdated"}; + StorageVectorBuffer curr_casters_updated = {"CurrCastersUpdated"}; + + Manager manager; + { + /* Simulate 1 object moving and 1 object static with changing resource index. */ + float4x4 obmat = float4x4::identity(); + float4x4 obmat2 = from_loc_rot_scale( + float3(1.0f), Quaternion::identity(), float3(0.5f)); + float3 half_extent = float3(0.24f, 0.249f, 0.001f); + + { + manager.begin_sync(); + ResourceHandle hdl = manager.resource_handle(obmat, float3(0.5f, 0.5f, -1.0f), half_extent); + manager.resource_handle(obmat2); + manager.end_sync(); + past_casters_updated.append(hdl.resource_index()); + past_casters_updated.push_update(); + } + { + manager.begin_sync(); + manager.resource_handle(obmat2); + ResourceHandle hdl = manager.resource_handle(obmat, float3(-1.0f, 0.5f, -1.0f), half_extent); + manager.end_sync(); + curr_casters_updated.append(hdl.resource_index()); + curr_casters_updated.push_update(); + } + } + + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + tiles_data.clear_to_zero(); + + { + ShadowTileMap tilemap(0 * SHADOW_TILEDATA_PER_TILEMAP); + tilemap.sync_cubeface(float4x4::identity(), 0.01f, 1.0f, Z_NEG, 0.0f); + tilemaps_data.append(tilemap); + } + { + ShadowTileMap tilemap(1 * SHADOW_TILEDATA_PER_TILEMAP); + tilemap.sync_orthographic(float4x4::identity(), int2(0), 1, 0.0f, SHADOW_PROJECTION_CLIPMAP); + tilemaps_data.append(tilemap); + } + + tilemaps_data.push_update(); + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_tag_update"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.bind_ssbo("bounds_buf", &manager.bounds_buf.previous()); + pass.bind_ssbo("resource_ids_buf", past_casters_updated); + pass.dispatch(int3(past_casters_updated.size(), 1, tilemaps_data.size())); + pass.bind_ssbo("bounds_buf", &manager.bounds_buf.current()); + pass.bind_ssbo("resource_ids_buf", curr_casters_updated); + pass.dispatch(int3(curr_casters_updated.size(), 1, tilemaps_data.size())); + + manager.submit(pass); + GPU_finish(); + + tiles_data.read(); + + /** The layout of these expected strings is Y down. */ + StringRefNull expected_lod0 = + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "xxxx----------------xxxxxxxx----" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------"; + StringRefNull expected_lod1 = + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "xx--------xxxx--" + "xx--------xxxx--" + "xx--------xxxx--" + "xx--------xxxx--" + "----------------" + "----------------"; + StringRefNull expected_lod2 = + "--------" + "--------" + "--------" + "--------" + "--------" + "x----xx-" + "x----xx-" + "--------"; + StringRefNull expected_lod3 = + "----" + "----" + "x-xx" + "x-xx"; + StringRefNull expected_lod4 = + "--" + "xx"; + StringRefNull expected_lod5 = "x"; + const uint lod0_len = SHADOW_TILEMAP_LOD0_LEN; + const uint lod1_len = SHADOW_TILEMAP_LOD1_LEN; + const uint lod2_len = SHADOW_TILEMAP_LOD2_LEN; + const uint lod3_len = SHADOW_TILEMAP_LOD3_LEN; + const uint lod4_len = SHADOW_TILEMAP_LOD4_LEN; + const uint lod5_len = SHADOW_TILEMAP_LOD5_LEN; + + auto stringify_result = [&](uint start, uint len) -> std::string { + std::string result = ""; + for (auto i : IndexRange(start, len)) { + result += (shadow_tile_unpack(tiles_data[i]).do_update) ? "x" : "-"; + } + return result; + }; + + EXPECT_EQ(stringify_result(0, lod0_len), expected_lod0); + EXPECT_EQ(stringify_result(lod0_len, lod1_len), expected_lod1); + EXPECT_EQ(stringify_result(lod0_len + lod1_len, lod2_len), expected_lod2); + EXPECT_EQ(stringify_result(lod0_len + lod1_len + lod2_len, lod3_len), expected_lod3); + EXPECT_EQ(stringify_result(lod0_len + lod1_len + lod2_len + lod3_len, lod4_len), expected_lod4); + EXPECT_EQ(stringify_result(lod0_len + lod1_len + lod2_len + lod3_len + lod4_len, lod5_len), + expected_lod5); + + GPU_shader_free(sh); + DRW_shaders_free(); +} +DRAW_TEST(eevee_shadow_tag_update) + +static void test_eevee_shadow_free() +{ + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + ShadowPageHeapBuf pages_free_data = {"PagesFreeBuf"}; + ShadowPageCacheBuf pages_cached_data = {"PagesCachedBuf"}; + ShadowPagesInfoDataBuf pages_infos_data = {"PagesInfosBuf"}; + + int tiles_index = 1; + int tile_orphaned_cached = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 5; + int tile_orphaned_allocated = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 6; + int tile_used_cached = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 260; + int tile_used_allocated = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 32; + int tile_used_unallocated = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 64; + int tile_unused_cached = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 9; + int tile_unused_allocated = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 8; + int page_free_count = SHADOW_MAX_PAGE - 6; + + for (uint i : IndexRange(2, page_free_count)) { + uint2 page = {i % SHADOW_PAGE_PER_ROW, i / SHADOW_PAGE_PER_ROW}; + pages_free_data[i] = page.x | (page.y << 16u); + } + pages_free_data.push_update(); + + pages_infos_data.page_free_count = page_free_count; + pages_infos_data.page_alloc_count = 0; + pages_infos_data.page_cached_next = 2u; + pages_infos_data.page_cached_start = 0u; + pages_infos_data.page_cached_end = 2u; + pages_infos_data.push_update(); + + for (uint i : IndexRange(pages_cached_data.size())) { + pages_cached_data[i] = uint2(-1, -1); + } + pages_cached_data[0] = uint2(0, tile_orphaned_cached); + pages_cached_data[1] = uint2(1, tile_used_cached); + pages_cached_data.push_update(); + + { + ShadowTileData tile; + + /* is_orphaned = true */ + tile.is_used = false; + tile.do_update = true; + + tile.is_cached = true; + tile.is_allocated = false; + tiles_data[tile_orphaned_cached] = shadow_tile_pack(tile); + + tile.is_cached = false; + tile.is_allocated = true; + tiles_data[tile_orphaned_allocated] = shadow_tile_pack(tile); + + /* is_orphaned = false */ + tile.do_update = false; + tile.is_used = true; + + tile.is_cached = true; + tile.is_allocated = false; + tiles_data[tile_used_cached] = shadow_tile_pack(tile); + + tile.is_cached = false; + tile.is_allocated = true; + tiles_data[tile_used_allocated] = shadow_tile_pack(tile); + + tile.is_cached = false; + tile.is_allocated = false; + tiles_data[tile_used_unallocated] = shadow_tile_pack(tile); + + tile.is_used = false; + tile.is_cached = true; + tile.is_allocated = false; + tiles_data[tile_unused_cached] = shadow_tile_pack(tile); + + tile.is_cached = false; + tile.is_allocated = true; + tiles_data[tile_unused_allocated] = shadow_tile_pack(tile); + + tiles_data.push_update(); + } + { + ShadowTileMapData tilemap = {}; + tilemap.tiles_index = tiles_index * SHADOW_TILEDATA_PER_TILEMAP; + tilemaps_data.append(tilemap); + tilemaps_data.push_update(); + } + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_page_free"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.bind_ssbo("pages_infos_buf", pages_infos_data); + pass.bind_ssbo("pages_free_buf", pages_free_data); + pass.bind_ssbo("pages_cached_buf", pages_cached_data); + pass.dispatch(int3(1, 1, tilemaps_data.size())); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + tiles_data.read(); + pages_infos_data.read(); + + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_orphaned_cached]).is_cached, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_orphaned_cached]).is_allocated, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_orphaned_allocated]).is_cached, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_orphaned_allocated]).is_allocated, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_used_cached]).is_cached, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_used_cached]).is_allocated, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_used_allocated]).is_cached, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_used_allocated]).is_allocated, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_used_unallocated]).is_cached, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_used_unallocated]).is_allocated, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_unused_cached]).is_cached, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_unused_cached]).is_allocated, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_unused_allocated]).is_cached, true); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_unused_allocated]).is_allocated, false); + EXPECT_EQ(pages_infos_data.page_alloc_count, 1); + EXPECT_EQ(pages_infos_data.page_free_count, page_free_count + 2); + EXPECT_EQ(pages_infos_data.page_cached_next, 3); + EXPECT_EQ(pages_infos_data.page_cached_end, 2); + + GPU_shader_free(sh); + DRW_shaders_free(); +} +DRAW_TEST(eevee_shadow_free) + +class TestDefrag { + private: + ShadowTileDataBuf tiles_data = {"tiles_data"}; + ShadowPageHeapBuf pages_free_data = {"PagesFreeBuf"}; + ShadowPageCacheBuf pages_cached_data = {"PagesCachedBuf"}; + ShadowPagesInfoDataBuf pages_infos_data = {"PagesInfosBuf"}; + + public: + TestDefrag(int allocation_count, + int descriptor_offset, + StringRefNull descriptor, + StringRefNull expect) + { + for (uint i : IndexRange(SHADOW_MAX_PAGE)) { + uint2 page = {i % SHADOW_PAGE_PER_ROW, i / SHADOW_PAGE_PER_ROW}; + pages_free_data[i] = page.x | (page.y << 16u); + } + + for (uint i : IndexRange(tiles_data.size())) { + tiles_data[i] = 0; + } + + int free_count = SHADOW_MAX_PAGE; + int tile_index = 0; + + for (uint i : IndexRange(pages_cached_data.size())) { + pages_cached_data[i] = uint2(-1, -1); + } + + int cached_index = descriptor_offset; + int hole_count = 0; + int inserted_count = 0; + ShadowTileData tile = {}; + tile.is_cached = true; + for (char c : descriptor) { + switch (c) { + case 'c': + tile.cache_index = cached_index++ % SHADOW_MAX_PAGE; + pages_cached_data[tile.cache_index] = uint2(pages_free_data[--free_count], tile_index); + tiles_data[tile_index++] = shadow_tile_pack(tile); + break; + case 'f': + pages_cached_data[cached_index++ % SHADOW_MAX_PAGE] = uint2(-1, -1); + hole_count++; + break; + case 'i': + tile.cache_index = (cached_index + inserted_count++) % SHADOW_MAX_PAGE; + pages_cached_data[tile.cache_index] = uint2(pages_free_data[--free_count], tile_index); + tiles_data[tile_index++] = shadow_tile_pack(tile); + break; + default: + break; + } + } + + pages_infos_data.page_alloc_count = allocation_count; + pages_infos_data.page_cached_next = cached_index + inserted_count; + pages_infos_data.page_free_count = free_count; + pages_infos_data.page_cached_start = descriptor_offset; + pages_infos_data.page_cached_end = cached_index; + + tiles_data.push_update(); + pages_infos_data.push_update(); + pages_free_data.push_update(); + pages_cached_data.push_update(); + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_page_defrag"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.bind_ssbo("pages_infos_buf", pages_infos_data); + pass.bind_ssbo("pages_free_buf", pages_free_data); + pass.bind_ssbo("pages_cached_buf", pages_cached_data); + pass.dispatch(int3(1, 1, 1)); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + tiles_data.read(); + pages_cached_data.read(); + pages_infos_data.read(); + + std::string result = ""; + int expect_cached_len = 0; + for (auto i : IndexRange(descriptor_offset, descriptor.size())) { + if (pages_cached_data[i % SHADOW_MAX_PAGE].y != -1) { + result += 'c'; + expect_cached_len++; + } + else { + result += 'f'; + } + } + EXPECT_EQ(expect, result); + + allocation_count = min_ii(allocation_count, SHADOW_MAX_PAGE); + + int additional_pages = max_ii(0, allocation_count - free_count); + int expected_free_count = max_ii(free_count, allocation_count); + int expected_start = descriptor_offset + hole_count + additional_pages; + int result_cached_len = pages_infos_data.page_cached_end - pages_infos_data.page_cached_start; + + if (expected_start > SHADOW_MAX_PAGE) { + expected_start -= SHADOW_MAX_PAGE; + } + + EXPECT_EQ(expected_free_count, pages_infos_data.page_free_count); + EXPECT_EQ(expected_start, pages_infos_data.page_cached_start); + EXPECT_EQ(expect_cached_len, result_cached_len); + EXPECT_EQ(pages_infos_data.page_cached_end, pages_infos_data.page_cached_next); + + GPU_shader_free(sh); + DRW_shaders_free(); + } +}; + +static void test_eevee_shadow_defrag() +{ + TestDefrag(0, 0, "cfi", "fcc"); + TestDefrag(0, 0, "fci", "fcc"); + TestDefrag(0, 47, "ccfcffccfcfciiiii", "fffffcccccccccccc"); + TestDefrag(10, SHADOW_MAX_PAGE - 5, "ccfcffccfcfciiiii", "fffffcccccccccccc"); + TestDefrag(SHADOW_MAX_PAGE - 8, 30, "ccfcffccfcfciiiii", "fffffffffcccccccc"); + TestDefrag(SHADOW_MAX_PAGE - 4, 30, "ccfcffccfcfciiiii", "fffffffffffffcccc"); + /* Over allocation but should not crash. */ + TestDefrag(SHADOW_MAX_PAGE + 4, 30, "ccfcffccfcfciiiii", "fffffffffffffffff"); +} +DRAW_TEST(eevee_shadow_defrag) + +class TestAlloc { + private: + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + ShadowPageHeapBuf pages_free_data = {"PagesFreeBuf"}; + ShadowPageCacheBuf pages_cached_data = {"PagesCachedBuf"}; + ShadowPagesInfoDataBuf pages_infos_data = {"PagesInfosBuf"}; + + public: + TestAlloc(int page_free_count) + { + int tiles_index = 1; + + for (uint i : IndexRange(0, page_free_count)) { + uint2 page = {i % SHADOW_PAGE_PER_ROW, i / SHADOW_PAGE_PER_ROW}; + pages_free_data[i] = page.x | (page.y << 16u); + } + pages_free_data.push_update(); + pages_cached_data.push_update(); + + pages_infos_data.page_free_count = page_free_count; + pages_infos_data.page_alloc_count = 1; + pages_infos_data.page_cached_next = 0u; + pages_infos_data.page_cached_start = 0u; + pages_infos_data.page_cached_end = 0u; + pages_infos_data.view_count = 0u; + pages_infos_data.page_size = 256u; + pages_infos_data.push_update(); + + int tile_allocated = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 5; + int tile_free = tiles_index * SHADOW_TILEDATA_PER_TILEMAP + 6; + + { + ShadowTileData tile; + + tile.is_used = true; + tile.do_update = false; + + tile.is_cached = false; + tile.is_allocated = false; + tiles_data[tile_free] = shadow_tile_pack(tile); + + tile.is_cached = false; + tile.is_allocated = true; + tiles_data[tile_allocated] = shadow_tile_pack(tile); + + tiles_data.push_update(); + } + { + ShadowTileMapData tilemap = {}; + tilemap.tiles_index = tiles_index * SHADOW_TILEDATA_PER_TILEMAP; + tilemaps_data.append(tilemap); + tilemaps_data.push_update(); + } + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_page_allocate"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.bind_ssbo("pages_infos_buf", pages_infos_data); + pass.bind_ssbo("pages_free_buf", pages_free_data); + pass.bind_ssbo("pages_cached_buf", pages_cached_data); + pass.dispatch(int3(1, 1, tilemaps_data.size())); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + tiles_data.read(); + pages_infos_data.read(); + + bool alloc_success = page_free_count >= 1; + + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_free]).do_update, alloc_success); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_free]).is_allocated, alloc_success); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_allocated]).do_update, false); + EXPECT_EQ(shadow_tile_unpack(tiles_data[tile_allocated]).is_allocated, true); + EXPECT_EQ(pages_infos_data.page_free_count, page_free_count - 1); + + GPU_shader_free(sh); + DRW_shaders_free(); + } +}; + +static void test_eevee_shadow_alloc() +{ + TestAlloc(SHADOW_MAX_PAGE); + TestAlloc(1); + TestAlloc(0); +} +DRAW_TEST(eevee_shadow_alloc) + +static void test_eevee_shadow_finalize() +{ + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + ShadowPageHeapBuf pages_free_data = {"PagesFreeBuf"}; + ShadowPageCacheBuf pages_cached_data = {"PagesCachedBuf"}; + ShadowPagesInfoDataBuf pages_infos_data = {"PagesInfosBuf"}; + + const uint lod0_len = SHADOW_TILEMAP_LOD0_LEN; + const uint lod1_len = SHADOW_TILEMAP_LOD1_LEN; + const uint lod2_len = SHADOW_TILEMAP_LOD2_LEN; + const uint lod3_len = SHADOW_TILEMAP_LOD3_LEN; + const uint lod4_len = SHADOW_TILEMAP_LOD4_LEN; + + const uint lod0_ofs = 0; + const uint lod1_ofs = lod0_len; + const uint lod2_ofs = lod1_ofs + lod1_len; + const uint lod3_ofs = lod2_ofs + lod2_len; + const uint lod4_ofs = lod3_ofs + lod3_len; + const uint lod5_ofs = lod4_ofs + lod4_len; + + for (auto i : IndexRange(SHADOW_TILEDATA_PER_TILEMAP)) { + tiles_data[i] = 0; + } + + { + ShadowTileData tile; + tile.is_used = true; + tile.is_allocated = true; + + tile.page = uint2(1, 0); + tile.do_update = false; + tiles_data[lod0_ofs] = shadow_tile_pack(tile); + + tile.page = uint2(2, 0); + tile.do_update = false; + tiles_data[lod1_ofs] = shadow_tile_pack(tile); + + tile.page = uint2(3, 0); + tile.do_update = true; + tiles_data[lod2_ofs] = shadow_tile_pack(tile); + + tile.page = uint2(4, 0); + tile.do_update = false; + tiles_data[lod3_ofs] = shadow_tile_pack(tile); + + tile.page = uint2(5, 0); + tile.do_update = true; + tiles_data[lod4_ofs] = shadow_tile_pack(tile); + + tile.page = uint2(6, 0); + tile.do_update = true; + tiles_data[lod5_ofs] = shadow_tile_pack(tile); + + tile.page = uint2(7, 0); + tile.do_update = true; + tiles_data[lod0_ofs + 8] = shadow_tile_pack(tile); + + tiles_data.push_update(); + } + { + ShadowTileMapData tilemap = {}; + tilemap.tiles_index = 0; + tilemap.projection_type = SHADOW_PROJECTION_CUBEFACE; + tilemaps_data.append(tilemap); + + tilemaps_data.push_update(); + } + { + pages_infos_data.page_free_count = -5; + pages_infos_data.page_alloc_count = 0; + pages_infos_data.page_cached_next = 0u; + pages_infos_data.page_cached_start = 0u; + pages_infos_data.page_cached_end = 0u; + pages_infos_data.view_count = 0u; + pages_infos_data.page_size = 256u; + pages_infos_data.push_update(); + } + + Texture tilemap_tx = {"tilemap_tx"}; + tilemap_tx.ensure_2d(GPU_R32UI, + int2(SHADOW_TILEMAP_RES), + GPU_TEXTURE_USAGE_HOST_READ | GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_SHADER_WRITE); + tilemap_tx.clear(uint4(0)); + + Texture render_map_tx = {"ShadowRenderMap", + GPU_R32UI, + GPU_TEXTURE_USAGE_HOST_READ | GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_SHADER_WRITE, + int2(SHADOW_TILEMAP_RES), + 1, /* Only one layer for the test. */ + nullptr, + SHADOW_TILEMAP_LOD + 1}; + render_map_tx.ensure_mip_views(); + + View shadow_multi_view = {"ShadowMultiView", 64, true}; + StorageBuffer clear_dispatch_buf; + StorageArrayBuffer clear_page_buf = {"clear_page_buf"}; + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_tilemap_finalize"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.bind_ssbo("pages_infos_buf", pages_infos_data); + pass.bind_image("tilemaps_img", tilemap_tx); + pass.bind_ssbo("view_infos_buf", shadow_multi_view.matrices_ubo_get()); + pass.bind_ssbo("clear_dispatch_buf", clear_dispatch_buf); + pass.bind_ssbo("clear_page_buf", clear_page_buf); + pass.bind_image("render_map_lod0_img", render_map_tx.mip_view(0)); + pass.bind_image("render_map_lod1_img", render_map_tx.mip_view(1)); + pass.bind_image("render_map_lod2_img", render_map_tx.mip_view(2)); + pass.bind_image("render_map_lod3_img", render_map_tx.mip_view(3)); + pass.bind_image("render_map_lod4_img", render_map_tx.mip_view(4)); + pass.bind_image("render_map_lod5_img", render_map_tx.mip_view(5)); + pass.dispatch(int3(1, 1, tilemaps_data.size())); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + + { + uint *pixels = tilemap_tx.read(GPU_DATA_UINT); + + std::string result = ""; + for (auto y : IndexRange(SHADOW_TILEMAP_RES)) { + for (auto x : IndexRange(SHADOW_TILEMAP_RES)) { + result += std::to_string(shadow_tile_unpack(pixels[y * SHADOW_TILEMAP_RES + x]).page.x); + } + } + + MEM_SAFE_FREE(pixels); + + /** The layout of these expected strings is Y down. */ + StringRefNull expected_pages = + "12334444755555556666666666666666" + "22334444555555556666666666666666" + "33334444555555556666666666666666" + "33334444555555556666666666666666" + "44444444555555556666666666666666" + "44444444555555556666666666666666" + "44444444555555556666666666666666" + "44444444555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "55555555555555556666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666" + "66666666666666666666666666666666"; + + EXPECT_EQ(expected_pages, result); + } + + { + auto stringify_lod = [](Span data) -> std::string { + std::string result = ""; + for (auto x : data) { + result += (x == 0xFFFFFFFFu) ? '-' : '0' + (x % 10); + } + return result; + }; + + /** The layout of these expected strings is Y down. */ + StringRefNull expected_lod0 = + "--------7-----------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------"; + + StringRefNull expected_lod1 = + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------" + "----------------"; + + StringRefNull expected_lod2 = + "3-------" + "--------" + "--------" + "--------" + "--------" + "--------" + "--------" + "--------"; + + StringRefNull expected_lod3 = + "----" + "----" + "----" + "----"; + + StringRefNull expected_lod4 = + "5-" + "--"; + + StringRefNull expected_lod5 = "6"; + + uint *pixels_lod0 = render_map_tx.read(GPU_DATA_UINT, 0); + uint *pixels_lod1 = render_map_tx.read(GPU_DATA_UINT, 1); + uint *pixels_lod2 = render_map_tx.read(GPU_DATA_UINT, 2); + uint *pixels_lod3 = render_map_tx.read(GPU_DATA_UINT, 3); + uint *pixels_lod4 = render_map_tx.read(GPU_DATA_UINT, 4); + uint *pixels_lod5 = render_map_tx.read(GPU_DATA_UINT, 5); + + EXPECT_EQ(stringify_lod(Span(pixels_lod0, lod0_len)), expected_lod0); + EXPECT_EQ(stringify_lod(Span(pixels_lod1, lod1_len)), expected_lod1); + EXPECT_EQ(stringify_lod(Span(pixels_lod2, lod2_len)), expected_lod2); + EXPECT_EQ(stringify_lod(Span(pixels_lod3, lod3_len)), expected_lod3); + EXPECT_EQ(stringify_lod(Span(pixels_lod4, lod4_len)), expected_lod4); + EXPECT_EQ(stringify_lod(Span(pixels_lod5, 1)), expected_lod5); + + MEM_SAFE_FREE(pixels_lod0); + MEM_SAFE_FREE(pixels_lod1); + MEM_SAFE_FREE(pixels_lod2); + MEM_SAFE_FREE(pixels_lod3); + MEM_SAFE_FREE(pixels_lod4); + MEM_SAFE_FREE(pixels_lod5); + } + + pages_infos_data.read(); + EXPECT_EQ(pages_infos_data.page_free_count, 0); + EXPECT_EQ(pages_infos_data.view_count, 1); + + GPU_shader_free(sh); + DRW_shaders_free(); +} +DRAW_TEST(eevee_shadow_finalize) + +static void test_eevee_shadow_page_mask() +{ + ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"}; + ShadowTileDataBuf tiles_data = {"tiles_data"}; + + { + ShadowTileMap tilemap(0); + tilemap.sync_cubeface(float4x4::identity(), 0.01f, 1.0f, Z_NEG, 0.0f); + tilemaps_data.append(tilemap); + } + + const uint lod0_len = SHADOW_TILEMAP_LOD0_LEN; + const uint lod1_len = SHADOW_TILEMAP_LOD1_LEN; + const uint lod2_len = SHADOW_TILEMAP_LOD2_LEN; + const uint lod3_len = SHADOW_TILEMAP_LOD3_LEN; + const uint lod4_len = SHADOW_TILEMAP_LOD4_LEN; + const uint lod5_len = SHADOW_TILEMAP_LOD5_LEN; + + const uint lod0_ofs = 0; + const uint lod1_ofs = lod0_ofs + lod0_len; + const uint lod2_ofs = lod1_ofs + lod1_len; + const uint lod3_ofs = lod2_ofs + lod2_len; + const uint lod4_ofs = lod3_ofs + lod3_len; + const uint lod5_ofs = lod4_ofs + lod4_len; + + { + ShadowTileData tile; + /* Init all LOD to true. */ + for (auto i : IndexRange(SHADOW_TILEDATA_PER_TILEMAP)) { + tile.is_used = true; + tiles_data[i] = shadow_tile_pack(tile); + } + + /* Init all of LOD0 to false. */ + for (auto i : IndexRange(square_i(SHADOW_TILEMAP_RES))) { + tile.is_used = false; + tiles_data[i] = shadow_tile_pack(tile); + } + + /* Bottom Left of the LOD0 to true. */ + for (auto y : IndexRange((SHADOW_TILEMAP_RES / 2) + 1)) { + for (auto x : IndexRange((SHADOW_TILEMAP_RES / 2) + 1)) { + tile.is_used = true; + tiles_data[x + y * SHADOW_TILEMAP_RES] = shadow_tile_pack(tile); + } + } + + /* All Bottom of the LOD0 to true. */ + for (auto x : IndexRange(SHADOW_TILEMAP_RES)) { + tile.is_used = true; + tiles_data[x] = shadow_tile_pack(tile); + } + + /* Bottom Left of the LOD1 to false. */ + /* Should still cover bottom LODs since it is itself fully masked */ + for (auto y : IndexRange((SHADOW_TILEMAP_RES / 8))) { + for (auto x : IndexRange((SHADOW_TILEMAP_RES / 8))) { + tile.is_used = false; + tiles_data[x + y * (SHADOW_TILEMAP_RES / 2) + lod0_len] = shadow_tile_pack(tile); + } + } + + /* Top right Center of the LOD1 to false. */ + /* Should un-cover 1 LOD2 tile. */ + { + int x = SHADOW_TILEMAP_RES / 4; + int y = SHADOW_TILEMAP_RES / 4; + tile.is_used = false; + tiles_data[x + y * (SHADOW_TILEMAP_RES / 2) + lod0_len] = shadow_tile_pack(tile); + } + + tiles_data.push_update(); + } + + tilemaps_data.push_update(); + + GPUShader *sh = GPU_shader_create_from_info_name("eevee_shadow_page_mask"); + + PassSimple pass("Test"); + pass.shader_set(sh); + pass.bind_ssbo("tilemaps_buf", tilemaps_data); + pass.bind_ssbo("tiles_buf", tiles_data); + pass.dispatch(int3(1, 1, tilemaps_data.size())); + + Manager manager; + manager.submit(pass); + GPU_finish(); + + tiles_data.read(); + + /** The layout of these expected strings is Y down. */ + StringRefNull expected_lod0 = + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "xxxxxxxxxxxxxxxxx---------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------" + "--------------------------------"; + StringRefNull expected_lod1 = + "--------xxxxxxxx" + "--------xxxxxxxx" + "--------xxxxxxxx" + "--------xxxxxxxx" + "--------xxxxxxxx" + "--------xxxxxxxx" + "--------xxxxxxxx" + "--------xxxxxxxx" + "xxxxxxxx-xxxxxxx" + "xxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxx"; + StringRefNull expected_lod2 = + "--------" + "--------" + "--------" + "--------" + "----x---" + "--------" + "--------" + "--------"; + StringRefNull expected_lod3 = + "----" + "----" + "----" + "----"; + StringRefNull expected_lod4 = + "--" + "--"; + StringRefNull expected_lod5 = "-"; + + auto stringify_result = [&](uint start, uint len) -> std::string { + std::string result = ""; + for (auto i : IndexRange(start, len)) { + result += (shadow_tile_unpack(tiles_data[i]).is_used) ? "x" : "-"; + } + return result; + }; + + EXPECT_EQ(stringify_result(lod0_ofs, lod0_len), expected_lod0); + EXPECT_EQ(stringify_result(lod1_ofs, lod1_len), expected_lod1); + EXPECT_EQ(stringify_result(lod2_ofs, lod2_len), expected_lod2); + EXPECT_EQ(stringify_result(lod3_ofs, lod3_len), expected_lod3); + EXPECT_EQ(stringify_result(lod4_ofs, lod4_len), expected_lod4); + EXPECT_EQ(stringify_result(lod5_ofs, lod5_len), expected_lod5); + + GPU_shader_free(sh); + DRW_shaders_free(); +} +DRAW_TEST(eevee_shadow_page_mask) + +} // namespace blender::draw diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 343fa34b3a5..000bf04697f 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4373,6 +4373,53 @@ static bool achannel_is_being_renamed(const bAnimContext *ac, return false; } +float ANIM_UI_get_keyframe_scale_factor(void) +{ + bTheme *btheme = UI_GetTheme(); + const float yscale_fac = btheme->space_action.keyframe_scale_fac; + + /* clamp to avoid problems with uninitialized values... */ + if (yscale_fac < 0.1f) { + return 1.0f; + } + return yscale_fac; +} + +float ANIM_UI_get_channel_height(void) +{ + return 0.8f * ANIM_UI_get_keyframe_scale_factor() * U.widget_unit; +} + +float ANIM_UI_get_channel_skip(void) +{ + return 0.1f * U.widget_unit; +} + +float ANIM_UI_get_first_channel_top(View2D *v2d) +{ + return UI_view2d_scale_get_y(v2d) * -UI_TIME_SCRUB_MARGIN_Y - ANIM_UI_get_channel_skip(); +} + +float ANIM_UI_get_channel_step(void) +{ + return ANIM_UI_get_channel_height() + ANIM_UI_get_channel_skip(); +} + +float ANIM_UI_get_channels_total_height(View2D *v2d, const int item_count) +{ + return -ANIM_UI_get_first_channel_top(v2d) + ANIM_UI_get_channel_step() * (item_count + 1); +} + +float ANIM_UI_get_channel_name_width(void) +{ + return 10 * U.widget_unit; +} + +float ANIM_UI_get_channel_button_width(void) +{ + return 0.8f * U.widget_unit; +} + void ANIM_channel_draw( bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index) { @@ -4566,7 +4613,8 @@ void ANIM_channel_draw( } /* check if there's enough space for the toggles if the sliders are drawn too */ - if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) { + if (!(draw_sliders) || + (BLI_rcti_size_x(&v2d->mask) > ANIM_UI_get_channel_button_width() / 2)) { /* protect... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) { offset += ICON_WIDTH; @@ -5247,7 +5295,7 @@ void ANIM_channel_draw_widgets(const bContext *C, } else { /* Cannot get property/cannot or rename for some reason, so clear rename index - * so that this doesn't hang around, and the name can be drawn normally - T47492 + * so that this doesn't hang around, and the name can be drawn normally - #47492 */ ac->ads->renameIndex = 0; WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL); @@ -5279,7 +5327,8 @@ void ANIM_channel_draw_widgets(const bContext *C, } /* check if there's enough space for the toggles if the sliders are drawn too */ - if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) { + if (!(draw_sliders) || + (BLI_rcti_size_x(&v2d->mask) > ANIM_UI_get_channel_button_width() / 2)) { /* protect... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) { offset -= ICON_WIDTH; diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index aa8b5796645..298b48a4a90 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -216,7 +216,7 @@ void ANIM_set_active_channel(bAnimContext *ac, static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, bAnimListElem *ale) { /* Armatures-Specific Feature: - * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737) + * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (#38737) */ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) { if ((ale->id) && (GS(ale->id->name) == ID_OB)) { @@ -667,7 +667,7 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f action_groups_remove_channel(act, fcu); /* if group has no more channels, remove it too, - * otherwise can have many dangling groups T33541. + * otherwise can have many dangling groups #33541. */ if (BLI_listbase_is_empty(&agrp->channels)) { BLI_freelinkN(&act->groups, agrp); @@ -2068,7 +2068,7 @@ static void setflag_anim_channels(bAnimContext *ac, * since we only want to apply this to channels we can "see", * and have these affect their relatives * - but for Graph Editor, this gets used also from main region - * where hierarchy doesn't apply T21276. + * where hierarchy doesn't apply #21276. */ if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) { /* graph editor (case 2) */ @@ -2718,7 +2718,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm ymax = NLACHANNEL_FIRST_TOP(ac); } else { - ymax = ACHANNEL_FIRST_TOP(ac); + ymax = ANIM_UI_get_first_channel_top(v2d); } /* loop over data, doing box select */ @@ -2726,7 +2726,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm float ymin; if (ale->type == ANIMTYPE_GPDATABLOCK) { - ymax -= ACHANNEL_STEP(ac); + ymax -= ANIM_UI_get_channel_step(); continue; } @@ -2734,7 +2734,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm ymin = ymax - NLACHANNEL_STEP(snla); } else { - ymin = ymax - ACHANNEL_STEP(ac); + ymin = ymax - ANIM_UI_get_channel_step(); } /* if channel is within border-select region, alter it */ @@ -2948,10 +2948,10 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2]) &channel_index); } else { - UI_view2d_listview_view_to_cell(ACHANNEL_NAMEWIDTH, - ACHANNEL_STEP(ac), + UI_view2d_listview_view_to_cell(ANIM_UI_get_channel_name_width(), + ANIM_UI_get_channel_step(), 0, - ACHANNEL_FIRST_TOP(ac), + ANIM_UI_get_first_channel_top(v2d), x, y, NULL, @@ -3067,10 +3067,10 @@ static int click_select_channel_object(bContext *C, } } - /* Change active object - regardless of whether it is now selected, see: T37883. + /* Change active object - regardless of whether it is now selected, see: #37883. * * Ensure we exit edit-mode on whatever object was active before - * to avoid getting stuck there, see: T48747. */ + * to avoid getting stuck there, see: #48747. */ ED_object_base_activate_with_mode_exit_if_needed(C, base); /* adds notifier */ if ((adt) && (adt->flag & ADT_UI_SELECTED)) { @@ -3484,10 +3484,10 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE /* figure out which channel user clicked in */ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y); - UI_view2d_listview_view_to_cell(ACHANNEL_NAMEWIDTH, - ACHANNEL_STEP(&ac), + UI_view2d_listview_view_to_cell(ANIM_UI_get_channel_name_width(), + ANIM_UI_get_channel_step(), 0, - ACHANNEL_FIRST_TOP(&ac), + ANIM_UI_get_first_channel_top(v2d), x, y, NULL, @@ -3499,7 +3499,8 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE /* set notifier that things have changed */ WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL); - return OPERATOR_FINISHED; + return WM_operator_flag_only_pass_through_on_press(OPERATOR_FINISHED | OPERATOR_PASS_THROUGH, + event); } static void ANIM_OT_channels_click(wmOperatorType *ot) diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 22c14983569..418331f84b1 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -241,7 +241,7 @@ static void animchan_sync_gplayer(bAnimListElem *ale) * The selection flags are used in the Dopesheet only, whereas * the active flag is used everywhere else. Hence, we try to * sync these here so that it all seems to be have as the user - * expects - T50184 + * expects - #50184 * * Assume that we only really do this when the active status changes. * (NOTE: This may prove annoying if it means selection is always lost) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f619837a3c5..ac73b7995f2 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -92,26 +92,6 @@ /* ************************************************************ */ /* Blender Context <-> Animation Context mapping */ -/* ----------- Private Stuff - General -------------------- */ - -/* Get vertical scaling factor (i.e. typically used for keyframe size) */ -static void animedit_get_yscale_factor(bAnimContext *ac) -{ - bTheme *btheme = UI_GetTheme(); - - /* grab scale factor directly from action editor setting - * NOTE: This theme setting doesn't have an ID, as it cannot be accessed normally - * since it is a float, and the theme settings methods can only handle chars. - */ - ac->yscale_fac = btheme->space_action.keyframe_scale_fac; - - /* clamp to avoid problems with uninitialized values... */ - if (ac->yscale_fac < 0.1f) { - ac->yscale_fac = 1.0f; - } - // printf("yscale_fac = %f\n", ac->yscale_fac); -} - /* ----------- Private Stuff - Action Editor ------------- */ /* Get shapekey data being edited (for Action Editor -> ShapeKey mode) */ @@ -243,7 +223,7 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction) /* sync scene's "selected keys only" flag with our "only selected" flag * - * XXX: This is a workaround for T55525. We shouldn't really be syncing the flags like this, + * XXX: This is a workaround for #55525. We shouldn't really be syncing the flags like this, * but it's a simpler fix for now than also figuring out how the next/prev keyframe * tools should work in the 3D View if we allowed full access to the timeline's * dopesheet filters (i.e. we'd have to figure out where to host those settings, @@ -408,9 +388,6 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) ac->spacetype = (area) ? area->spacetype : 0; ac->regiontype = (region) ? region->regiontype : 0; - /* Initialize default y-scale factor. */ - animedit_get_yscale_factor(ac); - /* get data context info */ /* XXX: if the below fails, try to grab this info from context instead... * (to allow for scripting). */ @@ -1095,7 +1072,7 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id /* Can only add this F-Curve if it is selected. */ if (ads->filterflag & ADS_FILTER_ONLYSEL) { - /* NOTE(@campbellbarton): The `seq == NULL` check doesn't look right + /* NOTE(@ideasman42): The `seq == NULL` check doesn't look right * (compared to other checks in this function which skip data that can't be found). * * This is done since the search for sequence strips doesn't use a global lookup: @@ -1383,7 +1360,7 @@ static size_t animfilter_act_group(bAnimContext *ac, * but the group isn't expanded (1)... * (1) this only matters if we actually care about the hierarchy though. * - Hierarchy matters: this hack should be applied - * - Hierarchy ignored: cases like T21276 won't work properly, unless we skip this hack + * - Hierarchy ignored: cases like #21276 won't work properly, unless we skip this hack */ if ( /* Care about hierarchy but group isn't expanded. */ @@ -3144,7 +3121,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, if (object_mode & OB_MODE_POSE) { /* When in pose-mode handle all pose-mode objects. * This avoids problems with pose-mode where objects may be unselected, - * where a selected bone of an unselected object would be hidden. see: T81922. */ + * where a selected bone of an unselected object would be hidden. see: #81922. */ if (!(base->object->mode & object_mode)) { return false; } @@ -3476,7 +3453,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, SpaceAction *saction = (SpaceAction *)ac->sl; bDopeSheet *ads = (saction) ? &saction->ads : NULL; - /* specially check for AnimData filter, see T36687. */ + /* specially check for AnimData filter, see #36687. */ if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) { /* all channels here are within the same AnimData block, hence this special case */ if (LIKELY(obact->adt)) { @@ -3497,7 +3474,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, { Key *key = (Key *)data; - /* specially check for AnimData filter, see T36687. */ + /* specially check for AnimData filter, see #36687. */ if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) { /* all channels here are within the same AnimData block, hence this special case */ if (LIKELY(key->adt)) { diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index 93d83ff5f8e..e319f4d8a03 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -184,7 +184,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) icon = RNA_struct_ui_icon(ptr.type); /* valid path - remove the invalid tag since we now know how to use it saving - * users manual effort to re-enable using "Revive Disabled FCurves" T29629. */ + * users manual effort to re-enable using "Revive Disabled FCurves" #29629. */ fcu->flag &= ~FCURVE_DISABLED; } else { diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index a2e137f854b..694eb1f7035 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -1350,7 +1350,7 @@ static int ed_marker_select( WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL); - /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails, see T25987. */ + /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails, see #25987. */ return ret_val | OPERATOR_PASS_THROUGH; } diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index f899e41149d..3dfcd076f17 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -195,7 +195,7 @@ static int add_driver_with_target(ReportList *UNUSED(reports), * - For transform properties, we want to automatically use "transform channel" instead * (The only issue is with quaternion rotations vs euler channels...) * - To avoid problems with transform properties depending on the final transform that they - * control (thus creating pseudo-cycles - see T48734), we don't use transform channels + * control (thus creating pseudo-cycles - see #48734), we don't use transform channels * when both the source and destinations are in same places. */ dvar = driver_add_new_variable(driver); diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 4a562f2b420..5bb95f1155e 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -103,7 +103,7 @@ static void fmodifier_reorder(bContext *C, Panel *panel, int new_index) const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(fcm->type); /* Cycles modifier has to be the first, so make sure it's kept that way. */ - if (fmi->requires & FMI_REQUIRES_ORIGINAL_DATA) { + if (fmi->requires_flag & FMI_REQUIRES_ORIGINAL_DATA) { WM_report(RPT_ERROR, "Modifier requires original data"); return; } @@ -113,7 +113,7 @@ static void fmodifier_reorder(bContext *C, Panel *panel, int new_index) /* Again, make sure we don't move a modifier before a cycles modifier. */ FModifier *fcm_first = modifiers->first; const FModifierTypeInfo *fmi_first = get_fmodifier_typeinfo(fcm_first->type); - if (fmi_first->requires & FMI_REQUIRES_ORIGINAL_DATA && new_index == 0) { + if (fmi_first->requires_flag & FMI_REQUIRES_ORIGINAL_DATA && new_index == 0) { WM_report(RPT_ERROR, "Modifier requires original data"); return; } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d0b978b7adf..6b1fdb977ff 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -22,6 +22,7 @@ #include "DNA_scene_types.h" #include "GPU_immediate.h" +#include "GPU_shader_shared.h" #include "GPU_state.h" #include "UI_interface.h" diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 49e40b39902..c435983be19 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -679,7 +679,7 @@ void sample_fcurve(FCurve *fcu) /* If next bezt is also selected, don't start sampling yet, * but instead wait for that one to reconsider, to avoid * changing the curve when sampling consecutive segments - * (T53229) + * (#53229) */ if (i < fcu->totvert - 1) { BezTriple *next = &fcu->bezt[i + 1]; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 96a9604a6f5..c6e9a62ae2a 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -2077,7 +2077,7 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UN /* Show a menu listing all keying-sets, the enum is expanded here to make use of the * operator that accesses the keying-set by name. This is important for the ability - * to assign shortcuts to arbitrarily named keying sets. See T89560. + * to assign shortcuts to arbitrarily named keying sets. See #89560. * These menu items perform the key-frame insertion (not this operator) * hence the #OPERATOR_INTERFACE return. */ uiPopupMenu *pup = UI_popup_menu_begin(C, WM_operatortype_name(op->type, op->ptr), ICON_NONE); @@ -2966,7 +2966,7 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter) /* check own animation data - specifically, the action it contains */ if ((ob->adt) && (ob->adt->action)) { - /* T41525 - When the active action is a NLA strip being edited, + /* #41525 - When the active action is a NLA strip being edited, * we need to correct the frame number to "look inside" the * remapped action */ @@ -3167,7 +3167,7 @@ bool ED_autokeyframe_property(bContext *C, if (only_if_property_keyed) { /* NOTE: We use rnaindex instead of fcu->array_index, * because a button may control all items of an array at once. - * E.g., color wheels (see T42567). */ + * E.g., color wheels (see #42567). */ BLI_assert((fcu->array_index == rnaindex) || (rnaindex == -1)); } changed = insert_keyframe(bmain, diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 3448ba1c017..a106ecb84e9 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -1119,7 +1119,7 @@ int ANIM_apply_keyingset( RNA_id_pointer_create(ksp->id, &id_ptr); if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) { arraylen = RNA_property_array_length(&ptr, prop); - /* start from start of array, instead of the previously specified index - T48020 */ + /* start from start of array, instead of the previously specified index - #48020 */ i = 0; } } diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 2ec0ea57e71..0e3748ad661 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -912,7 +912,7 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) armature_tag_select_mirrored(arm); /* Clear BONE_TRANSFORM flags - * - Used to prevent duplicate/canceling operations from occurring T34123. + * - Used to prevent duplicate/canceling operations from occurring #34123. * - #BONE_DONE cannot be used here as that's already used for mirroring. */ armature_clear_swap_done_flags(arm); @@ -929,7 +929,7 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) */ parent = ebo->parent; - /* skip bone if already handled, see T34123. */ + /* skip bone if already handled, see #34123. */ if ((ebo->flag & BONE_TRANSFORM) == 0) { /* only if selected and editable */ if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) { diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index 26ec05cc503..579583eb4ea 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -337,7 +337,7 @@ void ED_armature_bone_rename(Main *bmain, /* Fix all animdata that may refer to this bone - * we can't just do the ones attached to objects, - * since other ID-blocks may have drivers referring to this bone T29822. */ + * since other ID-blocks may have drivers referring to this bone #29822. */ /* XXX: the ID here is for armatures, * but most bone drivers are actually on the object instead. */ diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 90bd59f61bc..38b982e5342 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -151,7 +151,7 @@ void ED_operatormacros_armature(void) /* XXX would it be nicer to just be able to have standard extrude_move, * but set the forked property separate? - * that would require fixing a properties bug T19733. */ + * that would require fixing a properties bug #19733. */ ot = WM_operatortype_append_macro("ARMATURE_OT_extrude_forked", "Extrude Forked", "Create new bones from the selected joints and move them", diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 3ee0510ca7f..d2eb718401d 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -59,7 +59,7 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases, const uint hit_object = select_id & 0xFFFF; Base *base = NULL; EditBone *ebone = NULL; - /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ + /* TODO(@ideasman42): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; @@ -83,7 +83,7 @@ Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects, const uint hit_object = select_id & 0xFFFF; Object *ob = NULL; EditBone *ebone = NULL; - /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ + /* TODO(@ideasman42): optimize, eg: sort & binary search. */ for (uint ob_index = 0; ob_index < objects_len; ob_index++) { if (objects[ob_index]->runtime.select_id == hit_object) { ob = objects[ob_index]; @@ -107,7 +107,7 @@ Base *ED_armature_base_and_pchan_from_select_buffer(Base **bases, const uint hit_object = select_id & 0xFFFF; Base *base = NULL; bPoseChannel *pchan = NULL; - /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ + /* TODO(@ideasman42): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; @@ -1451,7 +1451,7 @@ static void armature_select_more_less(Object *ob, bool more) bArmature *arm = (bArmature *)ob->data; EditBone *ebone; - /* XXX(@campbellbarton): eventually we shouldn't need this. */ + /* XXX(@ideasman42): eventually we shouldn't need this. */ ED_armature_edit_sync_selection(arm->edbo); /* count bones & store selection state */ diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 6fb07dc7da6..3ed384ab820 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -162,7 +162,7 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) defgroup = BKE_object_defgroup_add_name(ob, bone->name); } else if (defgroup->flag & DG_LOCK_WEIGHT) { - /* In case vgroup already exists and is locked, do not modify it here. See T43814. */ + /* In case vgroup already exists and is locked, do not modify it here. See #43814. */ defgroup = NULL; } } @@ -477,7 +477,7 @@ void ED_object_vgroup_calc_from_armature(ReportList *reports, if (defbase_add) { /* It's possible there are DWeights outside the range of the current - * object's deform groups. In this case the new groups won't be empty T33889. */ + * object's deform groups. In this case the new groups won't be empty #33889. */ ED_vgroup_data_clamp_range(ob->data, defbase_tot); } } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 0465606e694..0391f25e922 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -597,7 +597,7 @@ static void armature_finalize_restpose(ListBase *bonelist, ListBase *editbonelis for (curBone = bonelist->first; curBone; curBone = curBone->next) { /* Set bone's local head/tail. * Note that it's important to use final parent's restpose (arm_mat) here, - * instead of setting those values from editbone's matrix (see T46010). */ + * instead of setting those values from editbone's matrix (see #46010). */ if (curBone->parent) { float parmat_inv[4][4]; @@ -749,7 +749,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) /* Fix parenting in a separate pass to ensure ebone->bone connections are valid at this point. * Do not set bone->head/tail here anymore, * using EditBone data for that is not OK since our later fiddling with parent's arm_mat - * (for roll conversion) may have some small but visible impact on locations (T46010). */ + * (for roll conversion) may have some small but visible impact on locations (#46010). */ for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { newBone = eBone->temp.bone; if (eBone->parent) { diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index e75d748653b..21938ad8727 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -168,7 +168,7 @@ bool ED_armature_pose_select_pick_bone(const Scene *scene, /* Since we do unified select, we don't shift+select a bone if the * armature object was not active yet. - * NOTE(@campbellbarton): special exception for armature mode so we can do multi-select + * NOTE(@ideasman42): special exception for armature mode so we can do multi-select * we could check for multi-select explicitly but think its fine to * always give predictable behavior in weight paint mode. */ if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) { @@ -230,7 +230,7 @@ bool ED_armature_pose_select_pick_bone(const Scene *scene, */ else if (arm->flag & ARM_HAS_VIZ_DEPS) { /* NOTE: ob not ob_act here is intentional - it's the source of the - * bones being selected [T37247] + * bones being selected [#37247]. */ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index 51071815823..7f384c36af0 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -524,7 +524,7 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) * change, thus changing the result we may be trying to record. */ /* NOTE: For some reason `pchan->chan_mat` can't be used here as it gives odd - * rotation/offset, see T38251. + * rotation/offset, see #38251. * Using `pchan->pose_mat` and bringing it back in bone space seems to work as expected! * This matches how visual key-framing works. */ BKE_armature_mat_pose_to_bone(pchan, pchan->pose_mat, pchan_xform_array[i].matrix); diff --git a/source/blender/editors/asset/ED_asset_handle.h b/source/blender/editors/asset/ED_asset_handle.h index 7bbba9b379e..b3d9b58b30e 100644 --- a/source/blender/editors/asset/ED_asset_handle.h +++ b/source/blender/editors/asset/ED_asset_handle.h @@ -25,8 +25,11 @@ struct AssetMetaData *ED_asset_handle_get_metadata(const struct AssetHandle *ass struct ID *ED_asset_handle_get_local_id(const struct AssetHandle *asset); ID_Type ED_asset_handle_get_id_type(const struct AssetHandle *asset); int ED_asset_handle_get_preview_icon_id(const struct AssetHandle *asset); -void ED_asset_handle_get_full_library_path(const struct AssetHandle *asset, - char r_full_lib_path[]); +void ED_asset_handle_get_full_library_path( + const struct AssetHandle *asset, + /* `1090` for #FILE_MAX_LIBEXTRA, + * rely on warnings to let us know if this gets out of sync. */ + char r_full_lib_path[1090]); #ifdef __cplusplus } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index f7107650f8c..1c2911cbe74 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1278,7 +1278,7 @@ void ED_curve_editnurb_make(Object *obedit) if (actkey) { // XXX strcpy(G.editModeTitleExtra, "(Key) "); - /* TODO(@campbellbarton): undo_system: investigate why this was needed. */ + /* TODO(@ideasman42): undo_system: investigate why this was needed. */ #if 0 undo_editmode_clear(); #endif diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index af3d439dd2e..66fb3cb06a3 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -577,7 +577,7 @@ static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke) cdd->vc.obedit = CTX_data_edit_object(C); /* Using an empty stroke complicates logic later, - * it's simplest to disallow early on (see: T94085). */ + * it's simplest to disallow early on (see: #94085). */ if (RNA_collection_is_empty(op->ptr, "stroke")) { MEM_freeN(cdd); BKE_report(op->reports, RPT_ERROR, "The \"stroke\" cannot be empty"); diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 59af21f8702..d80ebff2adc 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -157,6 +157,19 @@ bool curves_poll(bContext *C) return curves_poll_impl(C, false, false, false); } +static bool editable_curves_point_domain_poll(bContext *C) +{ + if (!curves::editable_curves_poll(C)) { + return false; + } + const Curves *curves_id = static_cast(CTX_data_active_object(C)->data); + if (curves_id->selection_domain != ATTR_DOMAIN_POINT) { + CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode"); + return false; + } + return true; +} + using bke::CurvesGeometry; namespace convert_to_particle_system { @@ -780,21 +793,19 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) if (curves.points_num() == 0) { continue; } - const GVArray src = attributes.lookup(".selection", domain); - if (src.is_empty()) { - continue; - } - const CPPType &type = src.type(); - void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__); - src.materialize(dst); + if (const GVArray src = attributes.lookup(".selection", domain)) { + const CPPType &type = src.type(); + void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__); + src.materialize(dst); - attributes.remove(".selection"); - if (!attributes.add(".selection", - domain, - bke::cpp_type_to_custom_data_type(type), - bke::AttributeInitMoveArray(dst))) { - MEM_freeN(dst); + attributes.remove(".selection"); + if (!attributes.add(".selection", + domain, + bke::cpp_type_to_custom_data_type(type), + bke::AttributeInitMoveArray(dst))) { + MEM_freeN(dst); + } } /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic @@ -931,19 +942,6 @@ static void CURVES_OT_select_random(wmOperatorType *ot) 1.0f); } -static bool select_end_poll(bContext *C) -{ - if (!curves::editable_curves_poll(C)) { - return false; - } - const Curves *curves_id = static_cast(CTX_data_active_object(C)->data); - if (curves_id->selection_domain != ATTR_DOMAIN_POINT) { - CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode"); - return false; - } - return true; -} - static int select_end_exec(bContext *C, wmOperator *op) { VectorSet unique_curves = curves::get_unique_editable_curves(*C); @@ -952,7 +950,7 @@ static int select_end_exec(bContext *C, wmOperator *op) for (Curves *curves_id : unique_curves) { CurvesGeometry &curves = curves_id->geometry.wrap(); - select_ends(curves, eAttrDomain(curves_id->selection_domain), amount, end_points); + select_ends(curves, amount, end_points); /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic * attribute for now. */ @@ -970,7 +968,7 @@ static void CURVES_OT_select_end(wmOperatorType *ot) ot->description = "Select end points of curves"; ot->exec = select_end_exec; - ot->poll = select_end_poll; + ot->poll = editable_curves_point_domain_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -983,6 +981,33 @@ static void CURVES_OT_select_end(wmOperatorType *ot) ot->srna, "amount", 1, 0, INT32_MAX, "Amount", "Number of points to select", 0, INT32_MAX); } +static int select_linked_exec(bContext *C, wmOperator * /*op*/) +{ + VectorSet unique_curves = get_unique_editable_curves(*C); + for (Curves *curves_id : unique_curves) { + CurvesGeometry &curves = curves_id->geometry.wrap(); + select_linked(curves); + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic + * attribute for now. */ + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + + return OPERATOR_FINISHED; +} + +static void CURVES_OT_select_linked(wmOperatorType *ot) +{ + ot->name = "Select Linked"; + ot->idname = __func__; + ot->description = "Select all points in curves with any point selection"; + + ot->exec = select_linked_exec; + ot->poll = editable_curves_point_domain_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + namespace surface_set { static bool surface_set_poll(bContext *C) @@ -1078,6 +1103,7 @@ void ED_operatortypes_curves() WM_operatortype_append(CURVES_OT_select_all); WM_operatortype_append(CURVES_OT_select_random); WM_operatortype_append(CURVES_OT_select_end); + WM_operatortype_append(CURVES_OT_select_linked); WM_operatortype_append(CURVES_OT_surface_set); } diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 81760cc2ee3..818e275b210 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -6,7 +6,9 @@ #include "BLI_array_utils.hh" #include "BLI_index_mask_ops.hh" +#include "BLI_lasso_2d.h" #include "BLI_rand.hh" +#include "BLI_rect.h" #include "BKE_attribute.hh" #include "BKE_crazyspace.hh" @@ -163,6 +165,21 @@ bool has_anything_selected(const bke::CurvesGeometry &curves) return !selection || contains(selection, true); } +bool has_anything_selected(const GSpan selection) +{ + if (selection.type().is()) { + return selection.typed().contains(true); + } + else if (selection.type().is()) { + for (const float elem : selection.typed()) { + if (elem > 0.0f) { + return true; + } + } + } + return false; +} + static void invert_selection(MutableSpan selection) { threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) { @@ -202,14 +219,12 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, } } -void select_ends(bke::CurvesGeometry &curves, - const eAttrDomain selection_domain, - int amount, - bool end_points) +void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points) { const bool was_anything_selected = has_anything_selected(curves); + const OffsetIndices points_by_curve = curves.points_by_curve(); bke::GSpanAttributeWriter selection = ensure_selection_attribute( - curves, selection_domain, CD_PROP_BOOL); + curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL); if (!was_anything_selected) { fill_selection_true(selection.span); } @@ -222,7 +237,6 @@ void select_ends(bke::CurvesGeometry &curves, MutableSpan selection_typed = selection.span.typed(); threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { - const OffsetIndices points_by_curve = curves.points_by_curve(); if (end_points) { selection_typed.slice(points_by_curve[curve_i].drop_back(amount)).fill(T(0)); } @@ -236,6 +250,23 @@ void select_ends(bke::CurvesGeometry &curves, selection.finish(); } +void select_linked(bke::CurvesGeometry &curves) +{ + const OffsetIndices points_by_curve = curves.points_by_curve(); + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL); + + threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { + for (const int curve_i : range) { + GMutableSpan selection_curve = selection.span.slice(points_by_curve[curve_i]); + if (has_anything_selected(selection_curve)) { + fill_selection_true(selection_curve); + } + } + }); + selection.finish(); +} + void select_random(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, uint32_t random_seed, @@ -285,6 +316,46 @@ void select_random(bke::CurvesGeometry &curves, selection.finish(); } +static void apply_selection_operation_at_index(GMutableSpan selection, + const int index, + const eSelectOp sel_op) +{ + if (selection.type().is()) { + MutableSpan selection_typed = selection.typed(); + switch (sel_op) { + case SEL_OP_ADD: + case SEL_OP_SET: + selection_typed[index] = true; + break; + case SEL_OP_SUB: + selection_typed[index] = false; + break; + case SEL_OP_XOR: + selection_typed[index] = !selection_typed[index]; + break; + default: + break; + } + } + else if (selection.type().is()) { + MutableSpan selection_typed = selection.typed(); + switch (sel_op) { + case SEL_OP_ADD: + case SEL_OP_SET: + selection_typed[index] = 1.0f; + break; + case SEL_OP_SUB: + selection_typed[index] = 0.0f; + break; + case SEL_OP_XOR: + selection_typed[index] = 1.0f - selection_typed[index]; + break; + default: + break; + } + } +} + /** * Helper struct for `find_closest_point_to_screen_co`. */ @@ -356,7 +427,7 @@ bool select_pick(const ViewContext &vc, bke::CurvesGeometry &curves, const eAttrDomain selection_domain, const SelectPick_Params ¶ms, - const int2 mval) + const int2 coord) { FindClosestPointData closest_point; bool found = find_closest_point_to_screen_co(*vc.depsgraph, @@ -364,7 +435,7 @@ bool select_pick(const ViewContext &vc, vc.rv3d, *vc.obact, curves, - float2(mval), + float2(coord), ED_view3d_select_dist_px(), closest_point); @@ -392,33 +463,188 @@ bool select_pick(const ViewContext &vc, elem_index = std::distance(curves.offsets().begin(), it) - 1; } - selection.span.type().to_static_type_tag([&](auto type_tag) { - using T = typename decltype(type_tag)::type; - if constexpr (std::is_void_v) { - BLI_assert_unreachable(); - } - else { - MutableSpan selection_typed = selection.span.typed(); - switch (params.sel_op) { - case SEL_OP_ADD: - case SEL_OP_SET: - selection_typed[elem_index] = T(1); - break; - case SEL_OP_SUB: - selection_typed[elem_index] = T(0); - break; - case SEL_OP_XOR: - selection_typed[elem_index] = T(1 - selection_typed[elem_index]); - break; - default: - break; - } - } - }); + apply_selection_operation_at_index(selection.span, elem_index, params.sel_op); selection.finish(); } return changed || found; } +bool select_box(const ViewContext &vc, + bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + const rcti &rect, + const eSelectOp sel_op) +{ + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, selection_domain, CD_PROP_BOOL); + + bool changed = false; + if (sel_op == SEL_OP_SET) { + fill_selection_false(selection.span); + changed = true; + } + + float4x4 projection; + ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr()); + + const bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact); + const OffsetIndices points_by_curve = curves.points_by_curve(); + if (selection_domain == ATTR_DOMAIN_POINT) { + threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) { + for (const int point_i : point_range) { + float2 pos_proj; + ED_view3d_project_float_v2_m4( + vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) { + apply_selection_operation_at_index(selection.span, point_i, sel_op); + changed = true; + } + } + }); + } + else if (selection_domain == ATTR_DOMAIN_CURVE) { + threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { + for (const int curve_i : curves_range) { + for (const int point_i : points_by_curve[curve_i]) { + float2 pos_proj; + ED_view3d_project_float_v2_m4( + vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) { + apply_selection_operation_at_index(selection.span, curve_i, sel_op); + changed = true; + break; + } + } + } + }); + } + selection.finish(); + + return changed; +} + +bool select_lasso(const ViewContext &vc, + bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + const Span coords, + const eSelectOp sel_op) +{ + rcti bbox; + const int(*coord_array)[2] = reinterpret_cast(coords.data()); + BLI_lasso_boundbox(&bbox, coord_array, coords.size()); + + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, selection_domain, CD_PROP_BOOL); + + bool changed = false; + if (sel_op == SEL_OP_SET) { + fill_selection_false(selection.span); + changed = true; + } + + float4x4 projection; + ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr()); + + const bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact); + const OffsetIndices points_by_curve = curves.points_by_curve(); + if (selection_domain == ATTR_DOMAIN_POINT) { + threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) { + for (const int point_i : point_range) { + float2 pos_proj; + ED_view3d_project_float_v2_m4( + vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + /* Check the lasso bounding box first as an optimization. */ + if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) && + BLI_lasso_is_point_inside( + coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) { + apply_selection_operation_at_index(selection.span, point_i, sel_op); + changed = true; + } + } + }); + } + else if (selection_domain == ATTR_DOMAIN_CURVE) { + threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { + for (const int curve_i : curves_range) { + for (const int point_i : points_by_curve[curve_i]) { + float2 pos_proj; + ED_view3d_project_float_v2_m4( + vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + /* Check the lasso bounding box first as an optimization. */ + if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) && + BLI_lasso_is_point_inside( + coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) { + apply_selection_operation_at_index(selection.span, curve_i, sel_op); + changed = true; + break; + } + } + } + }); + } + selection.finish(); + + return changed; +} + +bool select_circle(const ViewContext &vc, + bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + const int2 coord, + const float radius, + const eSelectOp sel_op) +{ + const float radius_sq = pow2f(radius); + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, selection_domain, CD_PROP_BOOL); + + bool changed = false; + if (sel_op == SEL_OP_SET) { + fill_selection_false(selection.span); + changed = true; + } + + float4x4 projection; + ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr()); + + const bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact); + const OffsetIndices points_by_curve = curves.points_by_curve(); + if (selection_domain == ATTR_DOMAIN_POINT) { + threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) { + for (const int point_i : point_range) { + float2 pos_proj; + ED_view3d_project_float_v2_m4( + vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) { + apply_selection_operation_at_index(selection.span, point_i, sel_op); + changed = true; + } + } + }); + } + else if (selection_domain == ATTR_DOMAIN_CURVE) { + threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { + for (const int curve_i : curves_range) { + for (const int point_i : points_by_curve[curve_i]) { + float2 pos_proj; + ED_view3d_project_float_v2_m4( + vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) { + apply_selection_operation_at_index(selection.span, curve_i, sel_op); + changed = true; + break; + } + } + } + }); + } + selection.finish(); + + return changed; +} + } // namespace blender::ed::curves diff --git a/source/blender/editors/curves/intern/curves_undo.cc b/source/blender/editors/curves/intern/curves_undo.cc index 5b02b401e4c..53efe629dc3 100644 --- a/source/blender/editors/curves/intern/curves_undo.cc +++ b/source/blender/editors/curves/intern/curves_undo.cc @@ -4,6 +4,8 @@ * \ingroup edcurves */ +#include "BLI_task.hh" + #include "BKE_context.h" #include "BKE_curves.hh" #include "BKE_main.h" diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 55f7319b2f0..7d568424c88 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -959,55 +959,60 @@ static int gizmo_cage2d_invoke(bContext *C, wmGizmo *gz, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_constrain_axis[2]) +static void gizmo_constrain_from_scale_part(int part, bool r_constrain_axis[2]) +{ + r_constrain_axis[0] = (part > ED_GIZMO_CAGE2D_PART_SCALE_MAX_X && + part < ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y) ? + true : + false; + r_constrain_axis[1] = (part > ED_GIZMO_CAGE2D_PART_SCALE && + part < ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y) ? + true : + false; +} + +static void gizmo_pivot_from_scale_part(int part, float r_pt[2]) { - bool x = true, y = true; switch (part) { + case ED_GIZMO_CAGE2D_PART_SCALE: { + ARRAY_SET_ITEMS(r_pt, 0.0, 0.0); + break; + } case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X: { ARRAY_SET_ITEMS(r_pt, 0.5, 0.0); - x = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X: { ARRAY_SET_ITEMS(r_pt, -0.5, 0.0); - x = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y: { ARRAY_SET_ITEMS(r_pt, 0.0, 0.5); - y = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y: { ARRAY_SET_ITEMS(r_pt, 0.0, -0.5); - y = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y: { ARRAY_SET_ITEMS(r_pt, 0.5, 0.5); - x = y = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y: { ARRAY_SET_ITEMS(r_pt, 0.5, -0.5); - x = y = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y: { ARRAY_SET_ITEMS(r_pt, -0.5, 0.5); - x = y = false; break; } case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y: { ARRAY_SET_ITEMS(r_pt, -0.5, -0.5); - x = y = false; break; } default: BLI_assert(0); } - r_constrain_axis[0] = x; - r_constrain_axis[1] = y; } static int gizmo_cage2d_modal(bContext *C, @@ -1105,46 +1110,52 @@ static int gizmo_cage2d_modal(bContext *C, else { /* scale */ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); - float pivot[2]; - bool constrain_axis[2] = {false}; + const int draw_style = RNA_enum_get(gz->ptr, "draw_style"); + float pivot[2]; if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) { - gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis); + gizmo_pivot_from_scale_part(gz->highlight_part, pivot); } else { zero_v2(pivot); } - /* Cursor deltas scaled to (-0.5..0.5). */ - float delta_orig[2], delta_curr[2]; - for (int i = 0; i < 2; i++) { - delta_orig[i] = ((data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / dims[i]) - - pivot[i]; - delta_curr[i] = ((point_local[i] - data->orig_matrix_offset[3][i]) / dims[i]) - pivot[i]; - } + bool constrain_axis[2] = {false}; + gizmo_constrain_from_scale_part(gz->highlight_part, constrain_axis); float scale[2] = {1.0f, 1.0f}; for (int i = 0; i < 2; i++) { if (constrain_axis[i] == false) { - if (delta_orig[i] < 0.0f) { - delta_orig[i] *= -1.0f; - delta_curr[i] *= -1.0f; - } - const int sign = signum_i(scale[i]); - - scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i])); + /* Original cursor position relative to pivot, remapped to [-1, 1] */ + const float delta_orig = (data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / + (dims[i] * len_v3(data->orig_matrix_offset[i])) - + pivot[i]; + const float delta_curr = (point_local[i] - data->orig_matrix_offset[3][i]) / + (dims[i] * len_v3(data->orig_matrix_offset[i])) - + pivot[i]; if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED) == 0) { - if (sign != signum_i(scale[i])) { + if (signum_i(delta_orig) != signum_i(delta_curr)) { scale[i] = 0.0f; + continue; } } + + /* Original cursor position does not exactly lie on the cage boundary due to margin. */ + const float delta_boundary = signf(delta_orig) * 0.5f - pivot[i]; + scale[i] = delta_curr / delta_boundary; } } if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) { if (constrain_axis[0] == false && constrain_axis[1] == false) { - scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f; + if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) { + /* So that the cursor lies on the circle. */ + scale[1] = scale[0] = len_v2(scale); + } + else { + scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f; + } } else if (constrain_axis[0] == false) { scale[1] = scale[0]; diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c index 598d437e246..7dd69f722fc 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -88,7 +88,10 @@ static void gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[3], /* -------------------------------------------------------------------- */ -static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_constrain_axis[3]) +static void gizmo_rect_pivot_from_scale_part(int part, + float r_pt[3], + bool r_constrain_axis[3], + bool has_translation) { if (part >= ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z && part <= ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z) { @@ -102,7 +105,7 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_con const float sign[3] = {0.5f, 0.0f, -0.5f}; for (int i = 0; i < 3; i++) { - r_pt[i] = sign[range[i]]; + r_pt[i] = has_translation ? sign[range[i]] : 0.0f; r_constrain_axis[i] = (range[i] == 1); } } @@ -512,41 +515,33 @@ static int gizmo_cage3d_modal(bContext *C, else { /* scale */ copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); + float pivot[3]; bool constrain_axis[3] = {false}; - - if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) { - gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis); - } - else { - zero_v3(pivot); - } - - /* Cursor deltas scaled to (-0.5..0.5). */ - float delta_orig[3], delta_curr[3]; - - for (int i = 0; i < 3; i++) { - delta_orig[i] = ((data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / dims[i]) - - pivot[i]; - delta_curr[i] = ((point_local[i] - data->orig_matrix_offset[3][i]) / dims[i]) - pivot[i]; - } + bool has_translation = transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE; + gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis, has_translation); float scale[3] = {1.0f, 1.0f, 1.0f}; for (int i = 0; i < 3; i++) { if (constrain_axis[i] == false) { - if (delta_orig[i] < 0.0f) { - delta_orig[i] *= -1.0f; - delta_curr[i] *= -1.0f; - } - const int sign = signum_i(scale[i]); - - scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i])); + /* Original cursor position relative to pivot, remapped to [-1, 1] */ + const float delta_orig = (data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / + (dims[i] * len_v3(data->orig_matrix_offset[i])) - + pivot[i]; + const float delta_curr = (point_local[i] - data->orig_matrix_offset[3][i]) / + (dims[i] * len_v3(data->orig_matrix_offset[i])) - + pivot[i]; if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED) == 0) { - if (sign != signum_i(scale[i])) { + if (signum_i(delta_orig) != signum_i(delta_curr)) { scale[i] = 0.0f; + continue; } } + + /* Original cursor position does not exactly lie on the cage boundary due to margin. */ + const float delta_boundary = signf(delta_orig) * 0.5f - pivot[i]; + scale[i] = delta_curr / delta_boundary; } } diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 44a3eae4072..cea9e4c4c95 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -528,7 +528,7 @@ static short annotation_stroke_addpoint(tGPsdata *p, /* store settings */ copy_v2_v2(pt->m_xy, mval); - /* T44932 - Pressure vals are unreliable, so ignore for now */ + /* #44932 - Pressure vals are unreliable, so ignore for now */ pt->pressure = 1.0f; pt->strength = 1.0f; pt->time = (float)(curtime - p->inittime); @@ -544,7 +544,7 @@ static short annotation_stroke_addpoint(tGPsdata *p, /* store settings */ copy_v2_v2(pt->m_xy, mval); - /* T44932 - Pressure vals are unreliable, so ignore for now */ + /* #44932 - Pressure vals are unreliable, so ignore for now */ pt->pressure = 1.0f; pt->strength = 1.0f; pt->time = (float)(curtime - p->inittime); @@ -620,7 +620,7 @@ static short annotation_stroke_addpoint(tGPsdata *p, /* store settings */ copy_v2_v2(pt->m_xy, mval); - /* T44932 - Pressure vals are unreliable, so ignore for now */ + /* #44932 - Pressure vals are unreliable, so ignore for now */ pt->pressure = 1.0f; pt->strength = 1.0f; pt->time = (float)(curtime - p->inittime); @@ -2064,7 +2064,7 @@ static void annotation_draw_apply_event( /* Convert from window-space to area-space mouse coordinates * add any x,y override position for fake events. */ if (p->flags & GP_PAINTFLAG_FIRSTRUN) { - /* The first run may be a drag event, see: T99368. */ + /* The first run may be a drag event, see: #99368. */ WM_event_drag_start_mval_fl(event, p->region, p->mval); p->mval[0] -= x; p->mval[1] -= y; @@ -2136,7 +2136,7 @@ static void annotation_draw_apply_event( /* Hack for pressure sensitive eraser on D+RMB when using a tablet: * The pen has to float over the tablet surface, resulting in - * zero pressure (T47101). Ignore pressure values if floating + * zero pressure (#47101). Ignore pressure values if floating * (i.e. "effectively zero" pressure), and only when the "active" * end is the stylus (i.e. the default when not eraser) */ @@ -2357,7 +2357,7 @@ static tGPsdata *annotation_stroke_begin(bContext *C, wmOperator *op) tGPsdata *p = op->customdata; /* we must check that we're still within the area that we're set up to work from - * otherwise we could crash (see bug T20586) + * otherwise we could crash (see bug #20586) */ if (CTX_wm_area(C) != p->area) { printf("\t\t\tGP - wrong area execution abort!\n"); @@ -2466,7 +2466,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve EVT_UPARROWKEY, EVT_ZKEY)) { /* allow some keys: - * - For frame changing T33412. + * - For frame changing #33412. * - For undo (during sketching sessions). */ } @@ -2503,7 +2503,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve /* Exit painting mode (and/or end current stroke) * * NOTE: cannot do RIGHTMOUSE (as is standard for canceling) - * as that would break polyline T32647. + * as that would break polyline #32647. */ if (event->val == KM_PRESS && ELEM(event->type, EVT_RETKEY, EVT_PADENTER, EVT_ESCKEY, EVT_SPACEKEY, EVT_EKEY)) { @@ -2516,7 +2516,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve * - LEFTMOUSE = standard drawing (all) / straight line drawing (all) / polyline (toolbox * only) * - RIGHTMOUSE = polyline (hotkey) / eraser (all) - * (Disabling RIGHTMOUSE case here results in bugs like T32647) + * (Disabling RIGHTMOUSE case here results in bugs like #32647) * also making sure we have a valid event value, to not exit too early */ if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && ELEM(event->val, KM_PRESS, KM_RELEASE)) { @@ -2704,7 +2704,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve else { /* update status indicators - cursor, header, etc. */ annotation_draw_status_indicators(C, p); - /* cursor may have changed outside our control - T44084 */ + /* cursor may have changed outside our control - #44084 */ annotation_draw_cursor_set(p); } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 24de50db397..7041dd25750 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -188,7 +188,7 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw, int keep_size = (int)((tgpw->gpd) && (tgpw->gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS)); gpencil_stroke_data.keep_size = keep_size; gpencil_stroke_data.pixfactor = tgpw->gpd->pixfactor; - /* xray mode always to 3D space to avoid wrong zdepth calculation (T60051) */ + /* xray mode always to 3D space to avoid wrong zdepth calculation (#60051) */ gpencil_stroke_data.xraymode = GP_XRAY_3DSPACE; gpencil_stroke_data.caps_start = tgpw->gps->caps[0]; gpencil_stroke_data.caps_end = tgpw->gps->caps[1]; diff --git a/source/blender/editors/gpencil/gpencil_armature.c b/source/blender/editors/gpencil/gpencil_armature.c index 2b7e09b7f05..664988d395c 100644 --- a/source/blender/editors/gpencil/gpencil_armature.c +++ b/source/blender/editors/gpencil/gpencil_armature.c @@ -207,7 +207,7 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) defgroup = BKE_object_defgroup_add_name(ob, bone->name); } else if (defgroup->flag & DG_LOCK_WEIGHT) { - /* In case vgroup already exists and is locked, do not modify it here. See T43814. */ + /* In case vgroup already exists and is locked, do not modify it here. See #43814. */ defgroup = NULL; } } diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 17ec33dc2bd..5cea5cc0780 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -1208,7 +1208,7 @@ static void gpencil_stroke_norm_curve_weights(Curve *cu, const float minmax_weig { const float delta = minmax_weights[0]; - /* when delta == minmax_weights[0] == minmax_weights[1], we get div by zero T35686. */ + /* when delta == minmax_weights[0] == minmax_weights[1], we get div by zero #35686. */ float fac; if (IS_EQF(delta, minmax_weights[1])) { fac = 1.0f; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index c6108f761a8..81576cc3e84 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -4064,7 +4064,7 @@ void GPENCIL_OT_reproject(wmOperatorType *ot) "keep_original", 0, "Keep Original", - "Keep original strokes and create a copy before reprojecting instead of reproject them"); + "Keep original strokes and create a copy before reprojecting"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP); RNA_def_float(ot->srna, "offset", 0.0f, 0.0f, 10.0f, "Surface Offset", "", 0.0f, 10.0f); @@ -4771,7 +4771,7 @@ void GPENCIL_OT_stroke_simplify(wmOperatorType *ot) /* identifiers */ ot->name = "Simplify Stroke"; ot->idname = "GPENCIL_OT_stroke_simplify"; - ot->description = "Simplify selected stroked reducing number of points"; + ot->description = "Simplify selected strokes, reducing number of points"; /* api callbacks */ ot->exec = gpencil_stroke_simplify_exec; @@ -4832,7 +4832,7 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot) /* identifiers */ ot->name = "Simplify Fixed Stroke"; ot->idname = "GPENCIL_OT_stroke_simplify_fixed"; - ot->description = "Simplify selected stroked reducing number of points using fixed algorithm"; + ot->description = "Simplify selected strokes, reducing number of points using fixed algorithm"; /* api callbacks */ ot->exec = gpencil_stroke_simplify_fixed_exec; diff --git a/source/blender/editors/gpencil/gpencil_edit_curve.c b/source/blender/editors/gpencil/gpencil_edit_curve.c index b669168aea7..cf29ce0755b 100644 --- a/source/blender/editors/gpencil/gpencil_edit_curve.c +++ b/source/blender/editors/gpencil/gpencil_edit_curve.c @@ -188,7 +188,7 @@ void GPENCIL_OT_stroke_editcurve_set_handle_type(wmOperatorType *ot) /* identifiers */ ot->name = "Set handle type"; ot->idname = "GPENCIL_OT_stroke_editcurve_set_handle_type"; - ot->description = "Set the type of a edit curve handle"; + ot->description = "Set the type of an edit curve handle"; /* api callbacks */ ot->invoke = WM_menu_invoke; diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 058cc417cc0..7f8ff54cc12 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -735,7 +735,7 @@ static void gpencil_create_extensions_radius(tGPDfill *tgpf) float tan2[3]; float d1; float d2; - float total_length = 0.f; + float total_length = 0.0f; for (int i = 1; i < gps->totpoints; i++) { if (i > 1) { copy_v3_v3(tan1, tan2); @@ -751,7 +751,7 @@ static void gpencil_create_extensions_radius(tGPDfill *tgpf) sub_v3_v3v3(curvature, tan2, tan1); float k = normalize_v3(curvature); k /= min_ff(d1, d2); - float radius = 1.f / k; + float radius = 1.0f / k; /* * The smaller the radius of curvature, the sharper the corner. * The thicker the line, the larger the radius of curvature it @@ -1003,8 +1003,8 @@ static void draw_mouse_position(tGPDfill *tgpf) uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); /* Draw mouse click position in Blue. */ - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); - GPU_point_size(point_size); + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + immUniform1f("size", point_size * M_SQRT2); immBegin(GPU_PRIM_POINTS, 1); immAttr4ubv(col, mouse_color); immVertex3fv(pos, &pt->x); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 5814248f24c..f5a50e768fc 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -764,7 +764,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p, /* store settings */ copy_v2_v2(pt->m_xy, mval); - /* T44932 - Pressure vals are unreliable, so ignore for now */ + /* #44932 - Pressure vals are unreliable, so ignore for now */ pt->pressure = 1.0f; pt->strength = 1.0f; pt->time = (float)(curtime - p->inittime); @@ -780,7 +780,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p, /* store settings */ copy_v2_v2(pt->m_xy, mval); - /* T44932 - Pressure vals are unreliable, so ignore for now */ + /* #44932 - Pressure vals are unreliable, so ignore for now */ pt->pressure = 1.0f; pt->strength = 1.0f; pt->time = (float)(curtime - p->inittime); @@ -2935,7 +2935,7 @@ static void gpencil_draw_apply_event(bContext *C, /* Hack for pressure sensitive eraser on D+RMB when using a tablet: * The pen has to float over the tablet surface, resulting in - * zero pressure (T47101). Ignore pressure values if floating + * zero pressure (#47101). Ignore pressure values if floating * (i.e. "effectively zero" pressure), and only when the "active" * end is the stylus (i.e. the default when not eraser) */ @@ -3343,7 +3343,7 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) tGPsdata *p = op->customdata; /* we must check that we're still within the area that we're set up to work from - * otherwise we could crash (see bug T20586) + * otherwise we could crash (see bug #20586) */ if (CTX_wm_area(C) != p->area) { printf("\t\t\tGP - wrong area execution abort!\n"); @@ -3689,7 +3689,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) if (ISKEYBOARD(event->type)) { if (ELEM(event->type, EVT_LEFTARROWKEY, EVT_DOWNARROWKEY, EVT_RIGHTARROWKEY, EVT_UPARROWKEY)) { /* allow some keys: - * - For frame changing T33412. + * - For frame changing #33412. * - For undo (during sketching sessions). */ } @@ -3735,7 +3735,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) /* toggle painting mode upon mouse-button movement * - LEFTMOUSE = standard drawing (all) / straight line drawing (all) * - RIGHTMOUSE = eraser (all) - * (Disabling RIGHTMOUSE case here results in bugs like T32647) + * (Disabling RIGHTMOUSE case here results in bugs like #32647) * also making sure we have a valid event value, to not exit too early */ if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && ELEM(event->val, KM_PRESS, KM_RELEASE)) { diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 0b11d6bf2ba..05718eb95e0 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -2487,7 +2487,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op) /* check if point is inside */ if (pt_distance <= radius_squared) { - /* only use this point if it is a better match than the current hit - T44685 */ + /* only use this point if it is a better match than the current hit - #44685 */ if (pt_distance < hit_distance) { hit_layer = gpl; hit_stroke = gps_active; diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index a7895b94600..0d61cbbdc6f 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -3327,6 +3327,14 @@ void ED_gpencil_layer_merge(bGPdata *gpd, gpf_dst->key_type = gpf_src->key_type; BLI_ghash_insert(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum), gpf_dst); } + + /* Copy current source frame to further frames + * that are keyframes in destination layer and not in source layer + * to keep the image equals. */ + if (gpf_dst->next && (!gpf_src->next || (gpf_dst->next->framenum < gpf_src->next->framenum))) { + gpf_dst = gpf_dst->next; + BKE_gpencil_layer_frame_get(gpl_src, gpf_dst->framenum, GP_GETFRAME_ADD_COPY); + } } /* Read all frames from merge layer and add strokes. */ diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 84512653a24..931e0c10575 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -34,7 +34,7 @@ typedef struct IMMDrawPixelsTexState { * To be used before calling #immDrawPixelsTex * Default shader is #GPU_SHADER_2D_IMAGE_COLOR * You can still set uniforms with: - * `GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);` + * `GPU_shader_uniform_*(shader, "name", value);` */ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin); diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 9eaaff9f7fa..a436fa43989 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -94,8 +94,6 @@ typedef struct bAnimContext { /** pointer to current reports list */ struct ReportList *reports; - /** Scale factor for height of channels (i.e. based on the size of keyframes). */ - float yscale_fac; } bAnimContext; /* Main Data container types */ @@ -430,28 +428,6 @@ ENUM_OPERATORS(eAnimFilter_Flags, ANIMFILTER_TMP_IGNORE_ONLYSEL); /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Channel Defines - * \{ */ - -/** Channel heights. */ -#define ACHANNEL_FIRST_TOP(ac) \ - (UI_view2d_scale_get_y(&(ac)->region->v2d) * -UI_TIME_SCRUB_MARGIN_Y - ACHANNEL_SKIP) -#define ACHANNEL_HEIGHT(ac) (0.8f * (ac)->yscale_fac * U.widget_unit) -#define ACHANNEL_SKIP (0.1f * U.widget_unit) -#define ACHANNEL_STEP(ac) (ACHANNEL_HEIGHT(ac) + ACHANNEL_SKIP) -/** Additional offset to give some room at the end. */ -#define ACHANNEL_TOT_HEIGHT(ac, item_amount) \ - (-ACHANNEL_FIRST_TOP(ac) + ACHANNEL_STEP(ac) * (item_amount + 1)) - -/** Channel widths. */ -#define ACHANNEL_NAMEWIDTH (10 * U.widget_unit) - -/** Channel toggle-buttons. */ -#define ACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit) - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name NLA Channel Defines * \{ */ @@ -612,6 +588,20 @@ typedef struct bAnimChannelType { void *(*setting_ptr)(bAnimListElem *ale, eAnimChannel_Settings setting, short *type); } bAnimChannelType; +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Channel dimensions API + * \{ */ + +float ANIM_UI_get_keyframe_scale_factor(void); +float ANIM_UI_get_channel_height(void); +float ANIM_UI_get_channel_skip(void); +float ANIM_UI_get_first_channel_top(View2D *v2d); +float ANIM_UI_get_channel_step(void); +float ANIM_UI_get_channels_total_height(View2D *v2d, int item_count); +float ANIM_UI_get_channel_name_width(void); +float ANIM_UI_get_channel_button_width(void); + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index a63e35313b1..2bfe99ea2bd 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -11,6 +11,7 @@ struct Curves; struct UndoType; struct SelectPick_Params; struct ViewContext; +struct rcti; #ifdef __cplusplus extern "C" { @@ -46,6 +47,8 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3] # include "BKE_curves.hh" +# include "ED_select_utils.h" + namespace blender::ed::curves { bool object_has_editable_curves(const Main &bmain, const Object &object); @@ -86,6 +89,11 @@ void fill_selection_true(GMutableSpan span); */ bool has_anything_selected(const bke::CurvesGeometry &curves); +/** + * Return true if any element in the span is selected, on either domain with either type. + */ +bool has_anything_selected(GSpan selection); + /** * Find curves that have any point selected (a selection factor greater than zero), * or curves that have their own selection factor greater than zero. @@ -103,8 +111,8 @@ IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_i * If the ".selection" attribute doesn't exist, create it with the requested type (bool or float). */ bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, - const eAttrDomain selection_domain, - const eCustomDataType create_type); + eAttrDomain selection_domain, + eCustomDataType create_type); /** * (De)select all the curves. @@ -112,7 +120,7 @@ bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves * \param action: One of SEL_TOGGLE, SEL_SELECT, SEL_DESELECT, or SEL_INVERT. See * "ED_select_utils.h". */ -void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, int action); +void select_all(bke::CurvesGeometry &curves, eAttrDomain selection_domain, int action); /** * Select the ends (front or back) of all the curves. @@ -120,10 +128,12 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, * \param amount: The amount of points to select from the front or back. * \param end_points: If true, select the last point(s), if false, select the first point(s). */ -void select_ends(bke::CurvesGeometry &curves, - const eAttrDomain selection_domain, - int amount, - bool end_points); +void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points); + +/** + * Select the points of all curves that have at least one point selected. + */ +void select_linked(bke::CurvesGeometry &curves); /** * Select random points or curves. @@ -133,20 +143,46 @@ void select_ends(bke::CurvesGeometry &curves, * will be selected, if set to 1.0 everything will be selected. */ void select_random(bke::CurvesGeometry &curves, - const eAttrDomain selection_domain, + eAttrDomain selection_domain, uint32_t random_seed, float probability); /** - * Select point or curve under the cursor. + * Select point or curve at a (screen-space) point. */ bool select_pick(const ViewContext &vc, bke::CurvesGeometry &curves, - const eAttrDomain selection_domain, + eAttrDomain selection_domain, const SelectPick_Params ¶ms, - const int2 mval); + int2 coord); +/** + * Select points or curves in a (screen-space) rectangle. + */ +bool select_box(const ViewContext &vc, + bke::CurvesGeometry &curves, + eAttrDomain selection_domain, + const rcti &rect, + eSelectOp sel_op); +/** + * Select points or curves in a (screen-space) poly shape. + */ +bool select_lasso(const ViewContext &vc, + bke::CurvesGeometry &curves, + eAttrDomain selection_domain, + Span coords, + eSelectOp sel_op); + +/** + * Select points or curves in a (screen-space) circle. + */ +bool select_circle(const ViewContext &vc, + bke::CurvesGeometry &curves, + eAttrDomain selection_domain, + int2 coord, + float radius, + eSelectOp sel_op); /** \} */ } // namespace blender::ed::curves diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index d4470c017bd..cf9b423dd7a 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -192,7 +192,7 @@ void ED_file_read_bookmarks(void); /** * Support updating the directory even when this isn't the active space - * needed so RNA properties update function isn't context sensitive, see T70255. + * needed so RNA properties update function isn't context sensitive, see #70255. */ void ED_file_change_dir_ex(struct bContext *C, struct ScrArea *area); void ED_file_change_dir(struct bContext *C); diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index a53042b70d6..5d779095d4e 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -79,7 +79,7 @@ struct FCurve *ED_action_fcurve_find(struct bAction *act, const char rna_path[], * \brief Lesser Key-framing API call. * * Update integer/discrete flags of the FCurve (used when creating/inserting keyframes, - * but also through RNA when editing an ID prop, see T37103). + * but also through RNA when editing an ID prop, see #37103). */ void update_autoflags_fcurve(struct FCurve *fcu, struct bContext *C, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 248ce8ec6b5..cfb71564671 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -88,7 +88,7 @@ void EDBM_mesh_make(struct Object *ob, int select_mode, bool add_key_index); void EDBM_mesh_free_data(struct BMEditMesh *em); /** * \warning This can invalidate the #Mesh runtime cache of other objects (for linked duplicates). - * Most callers should run #DEG_id_tag_update on `ob->data`, see: T46738, T46913. + * Most callers should run #DEG_id_tag_update on `ob->data`, see: #46738, #46913. * This ensures #BKE_object_free_derived_caches runs on all objects that use this mesh. */ void EDBM_mesh_load_ex(struct Main *bmain, struct Object *ob, bool free_data); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index baa84b550aa..cc1b615f6b1 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -241,6 +241,9 @@ void ED_object_parent(struct Object *ob, struct Object *parent, int type, const char *ED_object_ot_drop_named_material_tooltip(struct bContext *C, const char *name, const int mval[2]); +char *ED_object_ot_drop_geometry_nodes_tooltip(struct bContext *C, + struct PointerRNA *properties, + const int mval[2]); /* bitflags for enter/exit editmode */ enum { @@ -475,7 +478,7 @@ void ED_object_constraint_copy_for_pose(struct Main *bmain, struct bPoseChannel *pchan, struct bConstraint *con); -/* object_modes.c */ +/* object_modes.cc */ /** * Checks the mode to be set is compatible with the object diff --git a/source/blender/editors/include/ED_paint.h b/source/blender/editors/include/ED_paint.h index 048424cdee1..bd33a7e5cb4 100644 --- a/source/blender/editors/include/ED_paint.h +++ b/source/blender/editors/include/ED_paint.h @@ -24,7 +24,7 @@ struct wmKeyConfig; struct wmOperator; typedef struct PaintTileMap PaintTileMap; -/* paint_ops.c */ +/* paint_ops.cc */ void ED_operatortypes_paint(void); void ED_operatormacros_paint(void); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index 4e356499a1f..10f20054840 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -28,7 +28,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C, const struct rcti *rect, bool select); -/* sculpt_transform.c */ +/* sculpt_transform.cc */ void ED_sculpt_update_modal_transform(struct bContext *C, struct Object *ob); void ED_sculpt_init_transform(struct bContext *C, diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h index fe402b91b9c..96b933d9617 100644 --- a/source/blender/editors/include/ED_sequencer.h +++ b/source/blender/editors/include/ED_sequencer.h @@ -19,7 +19,13 @@ struct bContext; void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, bool deselect_all); -void ED_sequencer_deselect_all(struct Scene *scene); +/** + * Iterates over a scene's sequences and deselects all of them. + * + * \param scene: scene containing sequences to be deselected. + * \return true if any sequences were deselected; false otherwise. + */ +bool ED_sequencer_deselect_all(struct Scene *scene); bool ED_space_sequencer_maskedit_mask_poll(struct bContext *C); bool ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene); diff --git a/source/blender/editors/include/ED_undo.h b/source/blender/editors/include/ED_undo.h index 39bbd8adc75..3308391cca4 100644 --- a/source/blender/editors/include/ED_undo.h +++ b/source/blender/editors/include/ED_undo.h @@ -68,7 +68,7 @@ bool ED_undo_is_memfile_compatible(const struct bContext *C); * This is to avoid changes to a property making undo pushes * which are ignored by the undo-system. * For example, changing a brush property isn't stored by sculpt-mode undo steps. - * This workaround is needed until the limitation is removed, see: T61948. + * This workaround is needed until the limitation is removed, see: #61948. */ bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, struct ID *id); @@ -120,7 +120,7 @@ struct MemFile *ED_undosys_stack_memfile_get_active(struct UndoStack *ustack); * with memfile ones, this has to be called manually by relevant undo code. * * \note Only current known case for this is undoing a switch from Object to Sculpt mode (see - * T82388). + * #82388). * * \note Calling this ID by ID is not optimal, as it will loop over all #MemFile.chunks until it * finds the expected one. If this becomes an issue we'll have to add a mapping from session UUID diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 42406f727ed..519f3cc179f 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -18,7 +18,7 @@ struct IDRemapper; struct Main; struct bContext; -/* ed_util.c */ +/* ed_util.cc */ void ED_editors_init_for_undo(struct Main *bmain); void ED_editors_init(struct bContext *C); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 57939bd1f46..dc3951ab770 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -245,7 +245,7 @@ typedef enum { * Clamp the edge within the viewport limits defined by * #V3D_PROJ_TEST_CLIP_WIN, #V3D_PROJ_TEST_CLIP_NEAR & #V3D_PROJ_TEST_CLIP_FAR. * This resolves the problem of a visible edge having one of it's vertices - * behind the viewport. See: T32214. + * behind the viewport. See: #32214. * * This is not default behavior as it may be important for the screen-space location * of an edges vertex to represent that vertices location (instead of a location along the edge). @@ -760,7 +760,7 @@ bool ED_view3d_viewplane_get(struct Depsgraph *depsgraph, float *r_pixsize); /** - * Use instead of: `GPU_polygon_offset(rv3d->dist, ...)` see bug T37727. + * Use instead of: `GPU_polygon_offset(rv3d->dist, ...)` see bug #37727. */ void ED_view3d_polygon_offset(const struct RegionView3D *rv3d, float dist); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cf2c0ea2ebb..b04a276feb4 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -903,7 +903,7 @@ bool UI_but_active_only(const struct bContext *C, uiBut *but); /** * \warning This must run after other handlers have been added, - * otherwise the handler won't be removed, see: T71112. + * otherwise the handler won't be removed, see: #71112. */ bool UI_block_active_only_flagged_buttons(const struct bContext *C, struct ARegion *region, @@ -3061,7 +3061,7 @@ int UI_fontstyle_string_width(const struct uiFontStyle *fs, * only applying scale when drawing. This causes problems for fonts since kerning at * smaller sizes often makes them wider than a scaled down version of the larger text. * Resolve this by calculating the text at the on-screen size, - * returning the result scaled back to 1:1. See T92361. + * returning the result scaled back to 1:1. See #92361. */ int UI_fontstyle_string_width_with_block_aspect(const struct uiFontStyle *fs, const char *str, diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 9a46728097c..9023f1662ab 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -236,6 +236,7 @@ typedef enum ThemeColorID { TH_PATH_KEYFRAME_BEFORE, TH_PATH_KEYFRAME_AFTER, TH_CAMERA_PATH, + TH_CAMERA_PASSEPARTOUT, TH_LOCK_MARKER, TH_STITCH_PREVIEW_FACE, diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_color.cc b/source/blender/editors/interface/eyedroppers/eyedropper_color.cc index 94200e0ab4c..b051adc6c71 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_color.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_color.cc @@ -501,7 +501,7 @@ static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent * /*even /* init */ if (eyedropper_init(C, op)) { wmWindow *win = CTX_wm_window(C); - /* Workaround for de-activating the button clearing the cursor, see T76794 */ + /* Workaround for de-activating the button clearing the cursor, see #76794 */ UI_context_active_but_clear(C, win, CTX_wm_region(C)); WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER); diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_colorband.cc b/source/blender/editors/interface/eyedroppers/eyedropper_colorband.cc index 0f0155529c9..3b92d2d4cb3 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_colorband.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_colorband.cc @@ -286,7 +286,7 @@ static int eyedropper_colorband_invoke(bContext *C, wmOperator *op, const wmEven /* init */ if (eyedropper_colorband_init(C, op)) { wmWindow *win = CTX_wm_window(C); - /* Workaround for de-activating the button clearing the cursor, see T76794 */ + /* Workaround for de-activating the button clearing the cursor, see #76794 */ UI_context_active_but_clear(C, win, CTX_wm_region(C)); WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER); diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_datablock.cc b/source/blender/editors/interface/eyedroppers/eyedropper_datablock.cc index 81b8ca96170..db03a1e3301 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_datablock.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_datablock.cc @@ -307,7 +307,7 @@ static int datadropper_invoke(bContext *C, wmOperator *op, const wmEvent * /*eve /* init */ if (datadropper_init(C, op)) { wmWindow *win = CTX_wm_window(C); - /* Workaround for de-activating the button clearing the cursor, see T76794 */ + /* Workaround for de-activating the button clearing the cursor, see #76794 */ UI_context_active_but_clear(C, win, CTX_wm_region(C)); WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER); diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_depth.cc b/source/blender/editors/interface/eyedroppers/eyedropper_depth.cc index c026f3669ea..50c85aae494 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_depth.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_depth.cc @@ -302,7 +302,7 @@ static int depthdropper_invoke(bContext *C, wmOperator *op, const wmEvent * /*ev /* init */ if (depthdropper_init(C, op)) { wmWindow *win = CTX_wm_window(C); - /* Workaround for de-activating the button clearing the cursor, see T76794 */ + /* Workaround for de-activating the button clearing the cursor, see #76794 */ UI_context_active_but_clear(C, win, CTX_wm_region(C)); WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER); diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_driver.cc b/source/blender/editors/interface/eyedroppers/eyedropper_driver.cc index b5245fae2a9..9c2510056d1 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_driver.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_driver.cc @@ -161,7 +161,7 @@ static int driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent * /*e /* init */ if (driverdropper_init(C, op)) { wmWindow *win = CTX_wm_window(C); - /* Workaround for de-activating the button clearing the cursor, see T76794 */ + /* Workaround for de-activating the button clearing the cursor, see #76794 */ UI_context_active_but_clear(C, win, CTX_wm_region(C)); WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER); diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_gpencil_color.cc b/source/blender/editors/interface/eyedroppers/eyedropper_gpencil_color.cc index ca54fbc15c4..0c33b9034ad 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_gpencil_color.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_gpencil_color.cc @@ -49,12 +49,17 @@ #include "eyedropper_intern.hh" #include "interface_intern.hh" +typedef enum eGP_EyeMode { + GP_EYE_MATERIAL = 0, + GP_EYE_PALETTE = 1, +} eGP_EyeMode; + struct EyedropperGPencil { struct ColorManagedDisplay *display; /** color under cursor RGB */ float color[3]; /** Mode */ - int mode; + eGP_EyeMode mode; }; /* Helper: Draw status message while the user is running the operator */ @@ -79,7 +84,7 @@ static bool eyedropper_gpencil_init(bContext *C, wmOperator *op) display_device = scene->display_settings.display_device; eye->display = IMB_colormanagement_display_get_named(display_device); - eye->mode = RNA_enum_get(op->ptr, "mode"); + eye->mode = (eGP_EyeMode)RNA_enum_get(op->ptr, "mode"); return true; } @@ -228,10 +233,10 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed float col_conv[4]; - /* Convert from linear rgb space to display space because grease pencil colors are in display + /* Convert from linear rgb space to display space because palette colors are in display * space, and this conversion is needed to undo the conversion to linear performed by * eyedropper_color_sample_fl. */ - if (eye->display) { + if ((eye->display) && (eye->mode == GP_EYE_PALETTE)) { copy_v3_v3(col_conv, eye->color); IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display); } @@ -240,7 +245,7 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed } /* Add material or Palette color. */ - if (eye->mode == 0) { + if (eye->mode == GP_EYE_MATERIAL) { eyedropper_add_material(C, col_conv, only_stroke, only_fill, both); } else { @@ -348,8 +353,8 @@ static bool eyedropper_gpencil_poll(bContext *C) void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot) { static const EnumPropertyItem items_mode[] = { - {0, "MATERIAL", 0, "Material", ""}, - {1, "PALETTE", 0, "Palette", ""}, + {GP_EYE_MATERIAL, "MATERIAL", 0, "Material", ""}, + {GP_EYE_PALETTE, "PALETTE", 0, "Palette", ""}, {0, nullptr, 0, nullptr, nullptr}, }; @@ -369,5 +374,5 @@ void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot) ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "mode", items_mode, 0, "Mode", ""); + ot->prop = RNA_def_enum(ot->srna, "mode", items_mode, GP_EYE_MATERIAL, "Mode", ""); } diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index d64c1f56a17..aa5e870623d 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -572,7 +572,7 @@ static void ui_block_bounds_calc_popup( /* If given, adjust input coordinates such that they would generate real final popup position. * Needed to handle correctly floating panels once they have been dragged around, - * see T52999. */ + * see #52999. */ if (r_xy) { r_xy[0] = xy[0] + block->rect.xmin - raw_x; r_xy[1] = xy[1] + block->rect.ymin - raw_y; @@ -685,7 +685,7 @@ static int ui_but_calc_float_precision(uiBut *but, double value) int prec = int(ui_but_get_float_precision(but)); /* first check for various special cases: - * * If button is radians, we want additional precision (see T39861). + * * If button is radians, we want additional precision (see #39861). * * If prec is not set, we fallback to a simple default */ if (ui_but_is_unit_radians(but) && prec < 5) { prec = 5; @@ -886,7 +886,7 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) } /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position - * when scrolling without moving mouse (see T28432) */ + * when scrolling without moving mouse (see #28432) */ if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { oldbut->hardmax = but->hardmax; } @@ -1063,7 +1063,7 @@ bool UI_but_active_only(const bContext *C, ARegion *region, uiBlock *block, uiBu bool UI_block_active_only_flagged_buttons(const bContext *C, ARegion *region, uiBlock *block) { /* Running this command before end-block has run, means buttons that open menus - * won't have those menus correctly positioned, see T83539. */ + * won't have those menus correctly positioned, see #83539. */ BLI_assert(block->endblock); bool done = false; @@ -1310,7 +1310,7 @@ static bool ui_but_event_operator_string_from_panel(const bContext *C, IDP_AddToGroup(prop_panel, IDP_New(IDP_INT, ®ion_type_val, "region_type")); for (int i = 0; i < 2; i++) { - /* FIXME(@campbellbarton): We can't reasonably search all configurations - long term. */ + /* FIXME(@ideasman42): We can't reasonably search all configurations - long term. */ IDPropertyTemplate val = {0}; val.i = i; @@ -2130,7 +2130,7 @@ void UI_block_draw(const bContext *C, uiBlock *block) } /* XXX: figure out why invalid coordinates happen when closing render window */ - /* and material preview is redrawn in main window (temp fix for bug T23848) */ + /* and material preview is redrawn in main window (temp fix for bug #23848) */ if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) { ui_draw_but(C, region, &style, but, &rect); } @@ -4690,7 +4690,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, } else if (type == UI_BTYPE_SEARCH_MENU) { if (proptype == PROP_POINTER) { - /* Search buttons normally don't get undo, see: T54580. */ + /* Search buttons normally don't get undo, see: #54580. */ but->flag |= UI_BUT_UNDO; } } @@ -6272,7 +6272,7 @@ void UI_but_func_search_set(uiBut *but, if (search_exec_fn) { #ifdef DEBUG if (but->func) { - /* watch this, can be cause of much confusion, see: T47691 */ + /* watch this, can be cause of much confusion, see: #47691 */ printf("%s: warning, overwriting button callback with search function callback!\n", __func__); } diff --git a/source/blender/editors/interface/interface_align.cc b/source/blender/editors/interface/interface_align.cc index 2f7d4fc68ea..4ae92e38842 100644 --- a/source/blender/editors/interface/interface_align.cc +++ b/source/blender/editors/interface/interface_align.cc @@ -396,7 +396,7 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region) /* Note that this is typically less than ~20, and almost always under ~100. * Even so, we can't ensure this value won't exceed available stack memory. - * Fallback to allocation instead of using #alloca, see: T78636. */ + * Fallback to allocation instead of using #alloca, see: #78636. */ ButAlign butal_array_buf[256]; if (num_buttons <= ARRAY_SIZE(butal_array_buf)) { butal_array = butal_array_buf; @@ -537,7 +537,7 @@ static bool buts_are_horiz(uiBut *but1, uiBut *but2) float dx, dy; /* simple case which can fail if buttons shift apart - * with proportional layouts, see: T38602. */ + * with proportional layouts, see: #38602. */ if ((but1->rect.ymin == but2->rect.ymin) && (but1->rect.xmin != but2->rect.xmin)) { return true; } diff --git a/source/blender/editors/interface/interface_anim.cc b/source/blender/editors/interface/interface_anim.cc index 7a1c46640d2..e4263b7fc51 100644 --- a/source/blender/editors/interface/interface_anim.cc +++ b/source/blender/editors/interface/interface_anim.cc @@ -85,7 +85,7 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context) but->flag |= UI_BUT_ANIMATED; - /* T41525 - When the active action is a NLA strip being edited, + /* #41525 - When the active action is a NLA strip being edited, * we need to correct the frame number to "look inside" the * remapped action */ @@ -322,7 +322,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void * /*arg_dummy*/) return; } - /* FIXME(@campbellbarton): swapping active pointer is weak. */ + /* FIXME(@ideasman42): swapping active pointer is weak. */ std::swap(but_anim->active, but_decorate->active); wm->op_undo_depth++; diff --git a/source/blender/editors/interface/interface_context_menu.cc b/source/blender/editors/interface/interface_context_menu.cc index fb6213e13ab..0d697cb268f 100644 --- a/source/blender/editors/interface/interface_context_menu.cc +++ b/source/blender/editors/interface/interface_context_menu.cc @@ -44,7 +44,7 @@ #include "WM_types.h" /* This hack is needed because we don't have a good way to - * re-reference keymap items once added: T42944 */ + * re-reference keymap items once added: #42944 */ #define USE_KEYMAP_ADD_HACK /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/interface/interface_draw.cc b/source/blender/editors/interface/interface_draw.cc index 53a7d896427..79cfb2c50c9 100644 --- a/source/blender/editors/interface/interface_draw.cc +++ b/source/blender/editors/interface/interface_draw.cc @@ -1798,7 +1798,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, } /* Using some extra margin (-1.0f) for the coordinates used to complete the polygon * avoids the profile line crossing itself in some common situations, which can lead to - * incorrect triangulation. See T841183. */ + * incorrect triangulation. See #841183. */ if (add_left_tri && add_bottom_tri) { /* Add left side, bottom left corner, and bottom side points. */ table_coords[tot_points - 3][0] = profile->view_rect.xmin - 1.0f; diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 706d8c5b374..9a9c0d84160 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -94,7 +94,7 @@ /** * Check to avoid very small mouse-moves from jumping away from keyboard navigation, - * while larger mouse motion will override keyboard input, see: T34936. + * while larger mouse motion will override keyboard input, see: #34936. */ #define USE_KEYNAV_LIMIT @@ -140,7 +140,7 @@ * Instead of mapping cursor motion to the min/max, map the motion to the click-step. * * This value is multiplied by the click step to calculate a range to clamp the soft-range by. - * See: T68130 + * See: #68130 */ #define UI_DRAG_MAP_SOFT_RANGE_PIXEL_MAX 1000 @@ -384,7 +384,7 @@ struct uiHandleButtonData { /** * Behave as if #UI_BUT_DISABLED is set (without drawing grayed out). * Needed so non-interactive labels can be activated for the purpose of showing tool-tips, - * without them blocking interaction with nodes, see: T97386. + * without them blocking interaction with nodes, see: #97386. */ bool disable_force; @@ -549,7 +549,7 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val) const int dy = WM_event_absolute_delta_y(event); /* This event should be originally from event->type, - * converting wrong event into wheel is bad, see T33803. */ + * converting wrong event into wheel is bad, see #33803. */ BLI_assert(*type == MOUSEPAN); /* sign differs, reset */ @@ -752,7 +752,7 @@ static uiAfterFunc *ui_afterfunc_new() /** * For executing operators after the button is pressed. - * (some non operator buttons need to trigger operators), see: T37795. + * (some non operator buttons need to trigger operators), see: #37795. * * \param context_but: A button from which to get the context from (`uiBut.context`) for the * operator execution. @@ -932,7 +932,7 @@ static void ui_apply_but_undo(uiBut *but) /* Optionally override undo when undo system doesn't support storing properties. */ if (but->rnapoin.owner_id) { /* Exception for renaming ID data, we always need undo pushes in this case, - * because undo systems track data by their ID, see: T67002. */ + * because undo systems track data by their ID, see: #67002. */ /* Exception for active shape-key, since changing this in edit-mode updates * the shape key from object mode data. */ if (ELEM(but->rnaprop, &rna_ID_name, &rna_Object_active_shape_key_index)) { @@ -949,7 +949,7 @@ static void ui_apply_but_undo(uiBut *but) if (skip_undo == false) { /* XXX: disable all undo pushes from UI changes from sculpt mode as they cause memfile undo - * steps to be written which cause lag: T71434. */ + * steps to be written which cause lag: #71434. */ if (BKE_paintmode_get_active_from_context(static_cast(but->block->evil_C)) == PAINT_MODE_SCULPT) { skip_undo = true; @@ -1261,8 +1261,8 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) if (data->str) { /* This is intended to avoid unnecessary updates when the value stays the same, however there * are issues with the current implementation. It does not work with multi-button editing - * (T89996) or operator popups where a number button requires an update even if the value is - * unchanged (T89996). + * (#89996) or operator popups where a number button requires an update even if the value is + * unchanged (#89996). * * Trying to detect changes at this level is not reliable. Instead it could be done at the * level of RNA update/set, skipping RNA update if RNA set did not change anything, instead @@ -1517,7 +1517,7 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl /* Highly unlikely. */ printf("%s: Can't find button\n", __func__); /* While this avoids crashing, multi-button dragging will fail, - * which is still a bug from the user perspective. See T83651. */ + * which is still a bug from the user perspective. See #83651. */ continue; } @@ -1557,7 +1557,7 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl but->active->value = mbut_state->origvalue + value_delta; } - /* Clamp based on soft limits, see T40154. */ + /* Clamp based on soft limits, see #40154. */ CLAMP(but->active->value, double(but->softmin), double(but->softmax)); } @@ -3370,7 +3370,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) #ifdef USE_DRAG_MULTINUM /* this can happen from multi-drag */ if (data->applied_interactive) { - /* remove any small changes so canceling edit doesn't restore invalid value: T40538 */ + /* remove any small changes so canceling edit doesn't restore invalid value: #40538 */ data->cancel = true; ui_apply_but(C, but->block, but, data, true); data->cancel = false; @@ -3695,7 +3695,7 @@ static void ui_do_but_textedit( } else if (inbox) { /* if we allow activation on key press, - * it gives problems launching operators T35713. */ + * it gives problems launching operators #35713. */ if (event->val == KM_RELEASE) { button_activate_state(C, but, BUTTON_STATE_EXIT); retval = WM_UI_HANDLER_BREAK; @@ -4689,7 +4689,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons do_activate = (event->val == KM_RELEASE); } else if (!ui_do_but_extra_operator_icon(C, but, data, event)) { - /* Also use double-clicks to prevent fast clicks to leak to other handlers (T76481). */ + /* Also use double-clicks to prevent fast clicks to leak to other handlers (#76481). */ do_activate = ELEM(event->val, KM_PRESS, KM_DBL_CLICK); } } @@ -5903,7 +5903,7 @@ static int ui_do_but_GRIP( /* NOTE: Having to store org point in window space and recompute it to block "space" each time * is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which * returns different results when the block is inside a panel or not... - * See T37739. + * See #37739. */ int mx = event->xy[0]; @@ -6511,7 +6511,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, ui_color_picker_to_rgb_HSVCUBE_v(hsv_but, hsv, rgb); ui_perceptual_to_scene_linear_space(but, rgb); - /* clamp because with color conversion we can exceed range T34295. */ + /* clamp because with color conversion we can exceed range #34295. */ if (hsv_but->gradient_type == UI_GRAD_V_ALT) { clamp_axis_max_v3(rgb, but->softmax); } @@ -7954,10 +7954,10 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * * * An example of where this is needed is dragging node-sockets, where dragging a node-socket * could exit the button before the drag threshold was reached, disable the button then break - * handling of the #MOUSEMOVE event preventing the socket being dragged entirely, see: T96255. + * handling of the #MOUSEMOVE event preventing the socket being dragged entirely, see: #96255. * * Region level event handling is responsible for preventing events being passed - * through to parts of the UI that are logically behind this button, see: T92364. */ + * through to parts of the UI that are logically behind this button, see: #92364. */ return WM_UI_HANDLER_CONTINUE; } @@ -8261,7 +8261,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s /* Automatic open pull-down block timer. */ if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER) || /* Menu button types may draw as popovers, check for this case - * ignoring other kinds of menus (mainly enums). (see T66538). */ + * ignoring other kinds of menus (mainly enums). (see #66538). */ ((but->type == UI_BTYPE_MENU) && (UI_but_paneltype_get(but) || ui_but_menu_draw_as_popover(but)))) { if (data->used_mouse && !data->autoopentimer) { @@ -8793,7 +8793,7 @@ void UI_context_active_but_prop_handle(bContext *C, const bool handle_undo) { uiBut *activebut = ui_context_rna_button_active(C); if (activebut) { - /* TODO(@campbellbarton): look into a better way to handle the button change + /* TODO(@ideasman42): look into a better way to handle the button change * currently this is mainly so reset defaults works for the * operator redo panel. */ uiBlock *block = activebut->block; @@ -9039,7 +9039,7 @@ static void ui_handle_button_activate(bContext *C, */ static bool ui_handle_button_activate_by_type(bContext *C, ARegion *region, uiBut *but) { - if (but->type == UI_BTYPE_BUT_MENU) { + if (ELEM(but->type, UI_BTYPE_BUT_MENU, UI_BTYPE_ROW)) { /* mainly for operator buttons */ ui_handle_button_activate(C, region, but, BUTTON_ACTIVATE_APPLY); } @@ -9363,7 +9363,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) * * This is needed to make sure if a button was active, * it stays active while the mouse is over it. - * This avoids adding mouse-moves, see: T33466. */ + * This avoids adding mouse-moves, see: #33466. */ if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT, BUTTON_STATE_WAIT_DRAG)) { if (ui_but_find_mouse_over(region, event) == but) { button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER); @@ -9810,7 +9810,7 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, { BLI_assert(block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)); - /* annoying fix for T36269, this is a bit odd but in fact works quite well + /* annoying fix for #36269, this is a bit odd but in fact works quite well * don't mouse-out of a menu if another menu has been created after it. * if this causes problems we could remove it and check on a different fix - campbell */ if (menu->region->next) { @@ -10606,7 +10606,7 @@ static int ui_handle_menu_event(bContext *C, * popups which you can click again to close. * * Events handled above may have already set the return value, - * don't overwrite them, see: T61015. + * don't overwrite them, see: #61015. */ if ((inside == false) && (menu->menuretval == 0)) { uiSafetyRct *saferct = static_cast(block->saferct.first); @@ -11210,7 +11210,7 @@ static int ui_handle_menus_recursive(bContext *C, if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) { /* when there is a active search button and we close it, - * we need to reinit the mouse coords T35346. */ + * we need to reinit the mouse coords #35346. */ if (ui_region_find_active_but(menu->region) != but) { do_towards_reinit = true; } @@ -11358,15 +11358,15 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void * /*us if ((data->state == BUTTON_STATE_MENU_OPEN) && /* Make sure this popup isn't dragging a button. - * can happen with popovers (see T67882). */ + * can happen with popovers (see #67882). */ (ui_region_find_active_but(data->menu->region) == nullptr) && - /* make sure mouse isn't inside another menu (see T43247) */ + /* make sure mouse isn't inside another menu (see #43247) */ (ui_screen_region_find_mouse_over(screen, event) == nullptr) && ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER, UI_BTYPE_MENU) && (but_other = ui_but_find_mouse_over(region, event)) && (but != but_other) && ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER, UI_BTYPE_MENU) && /* Hover-opening menu's doesn't work well for buttons over one another - * along the same axis the menu is opening on (see T71719). */ + * along the same axis the menu is opening on (see #71719). */ (((data->menu->direction & (UI_DIR_LEFT | UI_DIR_RIGHT)) && BLI_rctf_isect_rect_x(&but->rect, &but_other->rect, nullptr)) || ((data->menu->direction & (UI_DIR_DOWN | UI_DIR_UP)) && @@ -11452,7 +11452,7 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata) * them into blender, even if there's opened popup like splash screen (sergey). * KM_DBL_CLICK: * Continue in case of double click so wm_handlers_do calls handler again with KM_PRESS - * event. This is needed to ensure correct button handling for fast clicking (T47532). + * event. This is needed to ensure correct button handling for fast clicking (#47532). */ retval = WM_UI_HANDLER_CONTINUE; diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index 93be39c9930..7e0b17aa128 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -1620,17 +1620,17 @@ static void icon_draw_cache_texture_flush_ex(GPUTexture *texture, GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR); GPU_shader_bind(shader); - const int data_binding = GPU_shader_get_uniform_block_binding(shader, "multi_rect_data"); + const int data_binding = GPU_shader_get_ubo_binding(shader, "multi_rect_data"); GPUUniformBuf *ubo = GPU_uniformbuf_create_ex( sizeof(MultiRectCallData), texture_draw_calls->drawcall_cache, __func__); GPU_uniformbuf_bind(ubo, data_binding); - const int img_binding = GPU_shader_get_texture_binding(shader, "image"); + const int img_binding = GPU_shader_get_sampler_binding(shader, "image"); GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false); GPUBatch *quad = GPU_batch_preset_quad(); GPU_batch_set_shader(quad, shader); - GPU_batch_draw_instanced(quad, texture_draw_calls->calls); + GPU_batch_draw_instance_range(quad, 0, texture_draw_calls->calls); GPU_texture_unbind(texture); GPU_uniformbuf_unbind(ubo); @@ -1797,25 +1797,25 @@ static void icon_draw_texture(float x, GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_ICON); GPU_shader_bind(shader); - const int img_binding = GPU_shader_get_texture_binding(shader, "image"); + const int img_binding = GPU_shader_get_sampler_binding(shader, "image"); const int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR); const int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon"); const int rect_geom_loc = GPU_shader_get_uniform(shader, "rect_geom"); if (rgb) { const float color[4] = {rgb[0], rgb[1], rgb[2], alpha}; - GPU_shader_uniform_vector(shader, color_loc, 4, 1, color); + GPU_shader_uniform_float_ex(shader, color_loc, 4, 1, color); } else { const float color[4] = {alpha, alpha, alpha, alpha}; - GPU_shader_uniform_vector(shader, color_loc, 4, 1, color); + GPU_shader_uniform_float_ex(shader, color_loc, 4, 1, color); } const float tex_color[4] = {x1, y1, x2, y2}; const float geom_color[4] = {x, y, x + w, y + h}; - GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, tex_color); - GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, geom_color); + GPU_shader_uniform_float_ex(shader, rect_tex_loc, 4, 1, tex_color); + GPU_shader_uniform_float_ex(shader, rect_geom_loc, 4, 1, geom_color); GPU_shader_uniform_1f(shader, "text_width", text_width); GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false); @@ -1890,7 +1890,7 @@ static void icon_draw_size(float x, } else if (di->type == ICON_TYPE_GEOM) { #ifdef USE_UI_TOOLBAR_HACK - /* TODO(@campbellbarton): scale icons up for toolbar, + /* TODO(@ideasman42): scale icons up for toolbar, * we need a way to detect larger buttons and do this automatic. */ { float scale = float(ICON_DEFAULT_HEIGHT_TOOLBAR) / float(ICON_DEFAULT_HEIGHT); @@ -1905,7 +1905,7 @@ static void icon_draw_size(float x, const bool geom_inverted = di->data.geom.inverted; /* This could re-generate often if rendered at different sizes in the one interface. - * TODO(@campbellbarton): support caching multiple sizes. */ + * TODO(@ideasman42): support caching multiple sizes. */ ImBuf *ibuf = di->data.geom.image_cache; if ((ibuf == nullptr) || (ibuf->x != w) || (ibuf->y != h) || (invert != geom_inverted)) { if (ibuf) { diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index 7366c1b051a..c2a78686608 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -43,7 +43,7 @@ #include "interface_intern.hh" /* Show an icon button after each RNA button to use to quickly set keyframes, - * this is a way to display animation/driven/override status, see T54951. */ + * this is a way to display animation/driven/override status, see #54951. */ #define UI_PROP_DECORATE /* Alternate draw mode where some buttons can use single icon width, * giving more room for the text at the expense of nicely aligned text. */ @@ -1009,7 +1009,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, ) { /* Also avoid setting 'align' if possible. Set the space to zero instead as aligning a large * number of labels can end up aligning thousands of buttons when displaying key-map search (a - * heavy operation), see: T78636. */ + * heavy operation), see: #78636. */ sub = uiLayoutRow(layout, layout->align); sub->space = 0; } @@ -3516,7 +3516,7 @@ void uiItemMenuFN(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc struct MenuItemLevel { wmOperatorCallContext opcontext; /* don't use pointers to the strings because python can dynamically - * allocate strings and free before the menu draws, see T27304. */ + * allocate strings and free before the menu draws, see #27304. */ char opname[OP_MAX_TYPENAME]; char propname[MAX_IDPROP_NAME]; PointerRNA rnapoin; @@ -3960,8 +3960,7 @@ static void ui_litem_layout_radial(uiLayout *litem) /* For the radial layout we will use Matt Ebb's design * for radiation, see http://mattebb.com/weblog/radiation/ - * also the old code at http://developer.blender.org/T5103 - */ + * also the old code at #5103. */ const int pie_radius = U.pie_menu_radius * UI_DPI_FAC; diff --git a/source/blender/editors/interface/interface_ops.cc b/source/blender/editors/interface/interface_ops.cc index 445f6cc5337..6e9d73f9847 100644 --- a/source/blender/editors/interface/interface_ops.cc +++ b/source/blender/editors/interface/interface_ops.cc @@ -1245,7 +1245,7 @@ bool UI_context_copy_to_selected_list(bContext *C, else if (GS(id->name) == ID_SCE) { /* Sequencer's ID is scene :/ */ /* Try to recursively find an RNA_Sequence ancestor, - * to handle situations like T41062... */ + * to handle situations like #41062... */ if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != nullptr) { /* Special case when we do this for 'Sequence.lock'. diff --git a/source/blender/editors/interface/interface_panel.cc b/source/blender/editors/interface/interface_panel.cc index 28aae7d779f..48fa0b9f0a3 100644 --- a/source/blender/editors/interface/interface_panel.cc +++ b/source/blender/editors/interface/interface_panel.cc @@ -1486,7 +1486,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) GPU_blend(GPU_BLEND_NONE); - /* Not essential, but allows events to be handled right up to the region edge (T38171). */ + /* Not essential, but allows events to be handled right up to the region edge (#38171). */ if (is_left) { pc_dyn->rect.xmin = v2d->mask.xmin; } @@ -2320,7 +2320,7 @@ int ui_handler_panel_region(bContext *C, UI_panel_category_active_set(region, pc_dyn->idname); ED_region_tag_redraw(region); - /* Reset scroll to the top (T38348). */ + /* Reset scroll to the top (#38348). */ UI_view2d_offset(®ion->v2d, -1.0f, 1.0f); retval = WM_UI_HANDLER_BREAK; diff --git a/source/blender/editors/interface/interface_region_menu_popup.cc b/source/blender/editors/interface/interface_region_menu_popup.cc index c02b1399868..7da9cbeb37b 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.cc +++ b/source/blender/editors/interface/interface_region_menu_popup.cc @@ -408,7 +408,7 @@ static uiPopupBlockHandle *ui_popup_menu_create( #if 0 /* if this is an rna button then we can assume its an enum * flipping enums is generally not good since the order can be - * important T28786. */ + * important #28786. */ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { pup->block->flag |= UI_BLOCK_NO_FLIP; } @@ -745,7 +745,7 @@ void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block) ui_popup_block_free(C, block->handle); /* In the case we have nested popups, - * closing one may need to redraw another, see: T48874 */ + * closing one may need to redraw another, see: #48874 */ LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) { ED_region_tag_refresh_ui(region); } diff --git a/source/blender/editors/interface/interface_region_popover.cc b/source/blender/editors/interface/interface_region_popover.cc index adc7f111d6b..d07f8abd9f8 100644 --- a/source/blender/editors/interface/interface_region_popover.cc +++ b/source/blender/editors/interface/interface_region_popover.cc @@ -397,7 +397,7 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap) pup->window = window; - /* TODO(@campbellbarton): we may want to make this configurable. + /* TODO(@ideasman42): we may want to make this configurable. * The begin/end stype of calling popups doesn't allow 'can_refresh' to be set. * For now close this style of popovers when accessed. */ UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN); diff --git a/source/blender/editors/interface/interface_region_popup.cc b/source/blender/editors/interface/interface_region_popup.cc index 520c3e9dc82..7943e7dc6fa 100644 --- a/source/blender/editors/interface/interface_region_popup.cc +++ b/source/blender/editors/interface/interface_region_popup.cc @@ -48,7 +48,7 @@ void ui_popup_translate(ARegion *region, const int mdiff[2]) /* update blocks */ LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { uiPopupBlockHandle *handle = block->handle; - /* Make empty, will be initialized on next use, see T60608. */ + /* Make empty, will be initialized on next use, see #60608. */ BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0); LISTBASE_FOREACH (uiSafetyRct *, saferct, &block->saferct) { @@ -214,7 +214,7 @@ static void ui_popup_block_position(wmWindow *window, /* Compute offset based on direction. */ float offset_x = 0, offset_y = 0; - /* Ensure buttons don't come between the parent button and the popup, see: T63566. */ + /* Ensure buttons don't come between the parent button and the popup, see: #63566. */ const float offset_overlap = max_ff(U.pixelsize, 1.0f); if (dir1 == UI_DIR_LEFT) { diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index edeeff868d6..fb87d940506 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -7,7 +7,7 @@ * ToolTip Region and Construction */ -/* TODO(@campbellbarton): +/* TODO(@ideasman42): * We may want to have a higher level API that initializes a timer, * checks for mouse motion and clears the tool-tip afterwards. * We never want multiple tool-tips at once @@ -996,7 +996,7 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) { uiTooltipData *data = MEM_cnew(__func__); - /* TODO(@campbellbarton): a way for gizmos to have their own descriptions (low priority). */ + /* TODO(@ideasman42): a way for gizmos to have their own descriptions (low priority). */ /* Operator Actions */ { @@ -1058,7 +1058,7 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) if (gz->type->target_property_defs_len) { wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz); for (int i = 0; i < gz->type->target_property_defs_len; i++) { - /* TODO(@campbellbarton): function callback descriptions. */ + /* TODO(@ideasman42): function callback descriptions. */ wmGizmoProperty *gz_prop = &gz_prop_array[i]; if (gz_prop->prop != nullptr) { const char *info = RNA_property_ui_description(gz_prop->prop); diff --git a/source/blender/editors/interface/interface_style.cc b/source/blender/editors/interface/interface_style.cc index 0df382a0d9e..96eef4fdb60 100644 --- a/source/blender/editors/interface/interface_style.cc +++ b/source/blender/editors/interface/interface_style.cc @@ -349,7 +349,7 @@ int UI_fontstyle_string_width_with_block_aspect(const uiFontStyle *fs, const char *str, const float aspect) { - /* FIXME(@campbellbarton): the final scale of the font is rounded which should be accounted for. + /* FIXME(@ideasman42): the final scale of the font is rounded which should be accounted for. * Failing to do so causes bad alignment when zoomed out very far in the node-editor. */ fontstyle_set_ex(fs, U.dpi_fac / aspect); return int(BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) * aspect); diff --git a/source/blender/editors/interface/interface_template_search_menu.cc b/source/blender/editors/interface/interface_template_search_menu.cc index e953119dfdc..547811ef1f8 100644 --- a/source/blender/editors/interface/interface_template_search_menu.cc +++ b/source/blender/editors/interface/interface_template_search_menu.cc @@ -468,7 +468,7 @@ static MenuSearch_Data *menu_items_from_ui_create( /* Exclude context menus because: * - The menu items are available elsewhere (and will show up multiple times). * - Menu items depend on exact context, making search results unpredictable - * (exact number of items selected for example). See design doc T74158. + * (exact number of items selected for example). See design doc #74158. * There is one exception, * as the outliner only exposes functionality via the context menu. */ GHashIterator iter; @@ -897,7 +897,7 @@ static MenuSearch_Data *menu_items_from_ui_create( * unless searching for something that isn't already in a menu (or scroll down). * * Keep this behind a developer only check: - * - Many operators need options to be set to give useful results, see: T74157. + * - Many operators need options to be set to give useful results, see: #74157. * - User who really prefer to list all operators can use #WM_OT_search_operator. */ if (U.flag & USER_DEVELOPER_UI) { diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 7b8fb7344b4..42c4bfd983e 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -2813,7 +2813,7 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single( /* no undo for buttons for operator redo panels */ UI_but_flag_disable(but, UI_BUT_UNDO); - /* only for popups, see T36109. */ + /* only for popups, see #36109. */ /* if button is operator's default property, and a text-field, enable focus for it * - this is used for allowing operators with popups to rename stuff with fewer clicks @@ -6553,12 +6553,12 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr) /* attach callbacks to compensate for missing properties update, * we don't know which keymap (item) is being modified there */ for (; but; but = but->next) { - /* operator buttons may store props for use (file selector, T36492) */ + /* operator buttons may store props for use (file selector, #36492) */ if (but->rnaprop) { UI_but_func_set(but, keymap_item_modified, ptr->data, nullptr); /* Otherwise the keymap will be re-generated which we're trying to edit, - * see: T47685 */ + * see: #47685 */ UI_but_flag_enable(but, UI_BUT_UPDATE_DELAY); } } diff --git a/source/blender/editors/interface/interface_utils.cc b/source/blender/editors/interface/interface_utils.cc index 4835e4c4f7f..af3e31837f7 100644 --- a/source/blender/editors/interface/interface_utils.cc +++ b/source/blender/editors/interface/interface_utils.cc @@ -978,7 +978,7 @@ void UI_butstore_free(uiBlock *block, uiButStore *bs_handle) * which then can't use the previous buttons state * ('ui_but_update_from_old_block' fails to find a match), * keeping the active button in the old block holding a reference - * to the button-state in the new block: see T49034. + * to the button-state in the new block: see #49034. * * Ideally we would manage moving the 'uiButStore', keeping a correct state. * All things considered this is the most straightforward fix - Campbell. diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 7b8015cf5a2..086b583d936 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -1157,7 +1157,7 @@ void UI_widgetbase_draw_cache_flush() MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH, (float(*)[4])g_widget_base_batch.params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); - GPU_batch_draw_instanced(batch, g_widget_base_batch.count); + GPU_batch_draw_instance_range(batch, 0, g_widget_base_batch.count); } g_widget_base_batch.count = 0; } @@ -1186,7 +1186,7 @@ void UI_widgetbase_draw_cache_end() static bool draw_widgetbase_batch_skip_draw_cache() { /* MacOS is known to have issues on Mac Mini and MacBook Pro with Intel Iris GPU. - * For example, T78307. */ + * For example, #78307. */ if (GPU_type_matches_ex(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) { return true; } @@ -2133,7 +2133,7 @@ static void widget_draw_text(const uiFontStyle *fstyle, int pos_x = rect->xmin + font_xofs + bounds.xmin + (bounds.xmax - bounds.xmin - ul_width) / 2; int pos_y = rect->ymin + font_yofs + bounds.ymin - U.pixelsize; - /* Use text output because direct drawing doesn't always work. See T89246. */ + /* Use text output because direct drawing doesn't always work. See #89246. */ BLF_position(fstyle->uifont_id, float(pos_x), pos_y, 0.0f); BLF_color4ubv(fstyle->uifont_id, wcol->text); BLF_draw(fstyle->uifont_id, "_", 2); @@ -2585,7 +2585,7 @@ static void widget_state_numslider(uiWidgetType *wt, if (color_blend != nullptr) { /* Set the slider 'item' so that it reflects state settings too. * De-saturate so the color of the slider doesn't conflict with the blend color, - * which can make the color hard to see when the slider is set to full (see T66102). */ + * which can make the color hard to see when the slider is set to full (see #66102). */ wt->wcol.item[0] = wt->wcol.item[1] = wt->wcol.item[2] = rgb_to_grayscale_byte(wt->wcol.item); color_blend_v3_v3(wt->wcol.item, color_blend, wcol_state->blend); color_ensure_contrast_v3(wt->wcol.item, wt->wcol.inner, 30); diff --git a/source/blender/editors/interface/resources.cc b/source/blender/editors/interface/resources.cc index 606f9d5a11f..5982f8ad1c9 100644 --- a/source/blender/editors/interface/resources.cc +++ b/source/blender/editors/interface/resources.cc @@ -803,6 +803,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) case TH_CAMERA_PATH: cp = ts->camera_path; break; + case TH_CAMERA_PASSEPARTOUT: + cp = ts->camera_passepartout; + break; case TH_LOCK_MARKER: cp = ts->lock_marker; break; diff --git a/source/blender/editors/interface/view2d.cc b/source/blender/editors/interface/view2d.cc index 51a3bd008af..a8d5b1ad22c 100644 --- a/source/blender/editors/interface/view2d.cc +++ b/source/blender/editors/interface/view2d.cc @@ -150,7 +150,7 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll) } /* Do not use mapped scroll here because we want to update scroller rects - * even if they are not displayed. For initialization purposes. See T75003. */ + * even if they are not displayed. For initialization purposes. See #75003. */ scroll = v2d->scroll; /* Scrollers are based off region-size: @@ -1034,7 +1034,7 @@ void UI_view2d_zoom_cache_reset(void) return; } /* While scaling we can accumulate fonts at many sizes (~20 or so). - * Not an issue with embedded font, but can use over 500Mb with i18n ones! See T38244. */ + * Not an issue with embedded font, but can use over 500Mb with i18n ones! See #38244. */ /* NOTE: only some views draw text, we could check for this case to avoid cleaning cache. */ BLF_cache_clear(); diff --git a/source/blender/editors/interface/view2d_ops.cc b/source/blender/editors/interface/view2d_ops.cc index b76f5f1e49f..37e5626b204 100644 --- a/source/blender/editors/interface/view2d_ops.cc +++ b/source/blender/editors/interface/view2d_ops.cc @@ -1858,7 +1858,7 @@ static void scroller_activate_init(bContext *C, UI_view2d_scrollers_calc(v2d, nullptr, &scrollers); /* Use a union of 'cur' & 'tot' in case the current view is far outside 'tot'. In this cases - * moving the scroll bars has far too little effect and the view can get stuck T31476. */ + * moving the scroll bars has far too little effect and the view can get stuck #31476. */ rctf tot_cur_union = v2d->tot; BLI_rctf_union(&tot_cur_union, &v2d->cur); diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index 100d56a6b0d..10857f53414 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -633,7 +633,7 @@ static int wm_alembic_import_exec(bContext *C, wmOperator *op) } } - /* Switch out of edit mode to avoid being stuck in it (T54326). */ + /* Switch out of edit mode to avoid being stuck in it (#54326). */ Object *obedit = CTX_data_edit_object(C); if (obedit) { ED_object_mode_set(C, OB_MODE_OBJECT); diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index e6426732584..6a3d8cf788b 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -75,7 +75,7 @@ const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = { const EnumPropertyItem rna_enum_usd_tex_import_mode_items[] = { {USD_TEX_IMPORT_NONE, "IMPORT_NONE", 0, "None", "Don't import textures"}, {USD_TEX_IMPORT_PACK, "IMPORT_PACK", 0, "Packed", "Import textures as packed data"}, - {USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to Textures Directory"}, + {USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to textures directory"}, {0, NULL, 0, NULL, NULL}, }; @@ -413,7 +413,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) int offset = 0; int sequence_len = 1; - /* Switch out of edit mode to avoid being stuck in it (T54326). */ + /* Switch out of edit mode to avoid being stuck in it (#54326). */ Object *obedit = CTX_data_edit_object(C); if (obedit) { ED_object_mode_set(C, OB_MODE_EDIT); @@ -675,7 +675,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot) "//textures/", FILE_MAXDIR, "Textures Directory", - "Path to the directory where imported textures will be copied "); + "Path to the directory where imported textures will be copied"); RNA_def_enum( ot->srna, diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c index b77786b2421..ad17063fb46 100644 --- a/source/blender/editors/lattice/editlattice_undo.c +++ b/source/blender/editors/lattice/editlattice_undo.c @@ -46,7 +46,7 @@ static CLG_LogRef LOG = {"ed.undo.lattice"}; /** \name Undo Conversion * \{ */ -/* TODO(@campbellbarton): this could contain an entire 'Lattice' struct. */ +/* TODO(@ideasman42): this could contain an entire 'Lattice' struct. */ typedef struct UndoLattice { BPoint *def; int pntsu, pntsv, pntsw, actbp; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 77014fde8a8..ea4050d0ba0 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -722,7 +722,7 @@ void ED_mask_draw_region( GPU_matrix_mul(stabmat); } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); - GPU_shader_uniform_vector( + GPU_shader_uniform_float_ex( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, buf_col); if (overlay_mode == MASK_OVERLAY_COMBINED) { diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 283969cee47..a0769fbaa5f 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -39,7 +39,7 @@ set(SRC editmesh_knife.c editmesh_knife_project.c editmesh_loopcut.c - editmesh_mask_extract.c + editmesh_mask_extract.cc editmesh_path.c editmesh_polybuild.c editmesh_preselect_edgering.c diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c index 19e23f4f212..e2f5bdacac7 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c @@ -455,7 +455,7 @@ void MESH_GGT_spin(struct wmGizmoGroupType *gzgt) gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool; gzgt->setup = gizmo_mesh_spin_init_setup; /* This works well with right click selection but overrides left-mouse selection - * when clicking which is needed to create a full 360 degree revolution, see: T89912. */ + * when clicking which is needed to create a full 360 degree revolution, see: #89912. */ // gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; gzgt->refresh = gizmo_mesh_spin_init_refresh; gzgt->message_subscribe = gizmo_mesh_spin_init_message_subscribe; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b7129b4b4d4..736555d678c 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -69,7 +69,7 @@ #define KMAXDIST (10 * U.dpi_fac) /* Max mouse distance from edge before not detecting it. */ /* WARNING: Knife float precision is fragile: - * Be careful before making changes here see: (T43229, T42864, T42459, T41164). + * Be careful before making changes here see: (#43229, #42864, #42459, #41164). */ #define KNIFE_FLT_EPS 0.00001f #define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS) @@ -198,7 +198,7 @@ typedef struct KnifeObjectInfo { * Optionally allocate triangle indices, these are needed for non-interactive knife * projection as multiple cuts are made without the BVH being updated. * Using these indices the it's possible to access `cagecos` even if the face has been cut - * and the loops in `em->looptris` no longer refer to the original triangles, see: T97153. + * and the loops in `em->looptris` no longer refer to the original triangles, see: #97153. */ const int (*tri_indices)[3]; @@ -2684,7 +2684,7 @@ static bool coinciding_edges(BMEdge *e1, BMEdge *e2) /* Callback used in point_is_visible to exclude hits on the faces that are the same * as or contain the hitting element (which is in user_data). - * Also (see T44492) want to exclude hits on faces that butt up to the hitting element + * Also (see #44492) want to exclude hits on faces that butt up to the hitting element * (e.g., when you double an edge by an edge split). */ static bool bm_ray_cast_cb_elem_not_in_face_check(BMFace *f, void *user_data) @@ -2975,10 +2975,10 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) face_tol = KNIFE_FLT_EPS_PX_FACE; } else { - /* Use 1/100th of a pixel, see T43896 (too big), T47910 (too small). + /* Use 1/100th of a pixel, see #43896 (too big), #47910 (too small). * * Update, leave this as is until we investigate not using pixel coords - * for geometry calculations: T48023. */ + * for geometry calculations: #48023. */ vert_tol = line_tol = face_tol = 0.5f; } @@ -3017,7 +3017,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) /* If this isn't from an existing BMVert, it may have been added to a BMEdge originally. * Knowing if the hit comes from an edge is important for edge-in-face checks later on. - * See: #knife_add_single_cut -> #knife_verts_edge_in_face, T42611. */ + * See: #knife_add_single_cut -> #knife_verts_edge_in_face, #42611. */ if (kfe_hit) { hit.kfe = kfe_hit; } @@ -4082,7 +4082,7 @@ static void knifetool_init(ViewContext *vc, const bool is_interactive) { /* Needed so multiple non-interactive cuts (also called knife-project) - * doesn't access indices of loops that were created by cutting, see: T97153. */ + * doesn't access indices of loops that were created by cutting, see: #97153. */ bool use_tri_indices = !is_interactive; kcd->vc = *vc; @@ -4303,7 +4303,7 @@ static void knifetool_finish_single_pre(KnifeTool_OpData *kcd, Object *ob) /** * A post version is needed to delay recalculating tessellation after making cuts. - * Without this, knife-project can't use the BVH tree to select geometry after a cut, see: T98349. + * Without this, knife-project can't use the BVH tree to select geometry after a cut, see: #98349. */ static void knifetool_finish_single_post(KnifeTool_OpData *UNUSED(kcd), Object *ob) { @@ -4322,7 +4322,7 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd) { /* Separate pre/post passes are needed because `em->looptris` recalculation from the 'post' pass * causes triangle indices in #KnifeTool_OpData.bvh to get out of sync. - * So perform all the cuts before doing any mesh recalculation, see: T101721. */ + * So perform all the cuts before doing any mesh recalculation, see: #101721. */ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) { Object *ob = kcd->objects[ob_index]; knifetool_finish_single_pre(kcd, ob); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 9a91d7836fe..b3a74be6f0c 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -176,7 +176,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) /* Enable grid-fill, so that intersecting loop-cut works as one would expect. * Note though that it will break edge-slide in this specific case. - * See T31939. */ + * See #31939. */ BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT, smoothness, @@ -193,7 +193,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) 0); /* when used in a macro the tessfaces will be recalculated anyway, - * this is needed here because modifiers depend on updated tessellation, see T45920 */ + * this is needed here because modifiers depend on updated tessellation, see #45920 */ EDBM_update(lcd->ob->data, &(const struct EDBMUpdate_Params){ .calc_looptri = true, diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.cc similarity index 81% rename from source/blender/editors/mesh/editmesh_mask_extract.c rename to source/blender/editors/mesh/editmesh_mask_extract.cc index 969a5cf52ed..83580b32884 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.cc @@ -49,7 +49,7 @@ static bool geometry_extract_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - if (ob != NULL && ob->mode == OB_MODE_SCULPT) { + if (ob != nullptr && ob->mode == OB_MODE_SCULPT) { if (ob->sculpt->bm) { CTX_wm_operator_poll_msg_set(C, "The geometry can not be extracted with dyntopo activated"); return false; @@ -59,7 +59,7 @@ static bool geometry_extract_poll(bContext *C) return false; } -typedef struct GeometryExtactParams { +struct GeometryExtractParams { /* For extracting Face Sets. */ int active_face_set; @@ -71,17 +71,17 @@ typedef struct GeometryExtactParams { int num_smooth_iterations; bool apply_shrinkwrap; bool add_solidify; -} GeometryExtractParams; +}; /* Function that tags in BMesh the faces that should be deleted in the extracted object. */ -typedef void(GeometryExtractTagMeshFunc)(struct BMesh *, GeometryExtractParams *); +using GeometryExtractTagMeshFunc = void(BMesh *, GeometryExtractParams *); static int geometry_extract_apply(bContext *C, wmOperator *op, GeometryExtractTagMeshFunc *tag_fn, GeometryExtractParams *params) { - struct Main *bmain = CTX_data_main(C); + Main *bmain = CTX_data_main(C); Object *ob = CTX_data_active_object(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); @@ -89,28 +89,24 @@ static int geometry_extract_apply(bContext *C, ED_object_sculptmode_exit(C, depsgraph); - BKE_sculpt_mask_layers_ensure(depsgraph, bmain, ob, NULL); + BKE_sculpt_mask_layers_ensure(depsgraph, bmain, ob, nullptr); /* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to * extract the geometry. */ CTX_data_ensure_evaluated_depsgraph(C); - Mesh *mesh = ob->data; + Mesh *mesh = static_cast(ob->data); Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id); const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh); - BMesh *bm; - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); + BMeshCreateParams bm_create_params{}; + bm_create_params.use_toolflags = true; + BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params); - BM_mesh_bm_from_me(bm, - new_mesh, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - })); + BMeshFromMeshParams mesh_to_bm_params{}; + mesh_to_bm_params.calc_face_normal = true; + mesh_to_bm_params.calc_vert_normal = true; + BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params); BMEditMesh *em = BKE_editmesh_create(bm); @@ -186,11 +182,9 @@ static int geometry_extract_apply(bContext *C, BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); BKE_id_free(bmain, new_mesh); - new_mesh = BKE_mesh_from_bmesh_nomain(bm, - (&(struct BMeshToMeshParams){ - .calc_object_remap = false, - }), - mesh); + BMeshToMeshParams bm_to_mesh_params{}; + bm_to_mesh_params.calc_object_remap = false; + new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh); BKE_editmesh_free_data(em); MEM_freeN(em); @@ -204,12 +198,13 @@ static int geometry_extract_apply(bContext *C, if (v3d && v3d->localvd) { local_view_bits = v3d->local_view_uuid; } - Object *new_ob = ED_object_add_type(C, OB_MESH, NULL, ob->loc, ob->rot, false, local_view_bits); - BKE_mesh_nomain_to_mesh(new_mesh, new_ob->data, new_ob); + Object *new_ob = ED_object_add_type( + C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits); + BKE_mesh_nomain_to_mesh(new_mesh, static_cast(new_ob->data), new_ob); /* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object. * TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */ - Mesh *new_ob_mesh = new_ob->data; + Mesh *new_ob_mesh = static_cast(new_ob->data); CustomData_free_layer_named(&new_ob_mesh->pdata, ".sculpt_face_set", new_ob_mesh->totpoly); /* Remove the mask from the new object so it can be sculpted directly after extracting. */ @@ -232,7 +227,7 @@ static int geometry_extract_apply(bContext *C, } WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob); - BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag(static_cast(new_ob->data), BKE_MESH_BATCH_DIRTY_ALL); DEG_relations_tag_update(bmain); DEG_id_tag_update(&new_ob->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_ob->data); @@ -294,7 +289,7 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op) * the OPTYPE_UNDO flag; having an initial undo step here * is just needed to preserve the active object pointer. * - * Fixes T103261. + * Fixes #103261. */ ED_undo_push_op(C, op); @@ -363,7 +358,7 @@ void MESH_OT_paint_mask_extract(wmOperatorType *ot) geometry_extract_props(ot->srna); } -static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e)) +static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { ED_workspace_status_text(C, TIP_("Click on the mesh to select a Face Set")); WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER); @@ -377,7 +372,7 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev case LEFTMOUSE: if (event->val == KM_PRESS) { WM_cursor_modal_restore(CTX_wm_window(C)); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); /* This modal operator uses and eyedropper to pick a Face Set from the mesh. This ensures * that the mouse clicked in a viewport region and its coordinates can be used to ray-cast @@ -389,8 +384,8 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev return OPERATOR_CANCELLED; } - const float mval[2] = {event->xy[0] - region->winrct.xmin, - event->xy[1] - region->winrct.ymin}; + const float mval[2] = {float(event->xy[0] - region->winrct.xmin), + float(event->xy[1] - region->winrct.ymin)}; Object *ob = CTX_data_active_object(C); const int face_set_id = ED_sculpt_face_sets_active_update_and_get(C, ob, mval); @@ -410,7 +405,7 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev case EVT_ESCKEY: case RIGHTMOUSE: { WM_cursor_modal_restore(CTX_wm_window(C)); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); return OPERATOR_CANCELLED; } @@ -488,40 +483,34 @@ static void slice_paint_mask(BMesh *bm, bool invert, bool fill_holes, float mask static int paint_mask_slice_exec(bContext *C, wmOperator *op) { - struct Main *bmain = CTX_data_main(C); + Main *bmain = CTX_data_main(C); Object *ob = CTX_data_active_object(C); View3D *v3d = CTX_wm_view3d(C); - BKE_sculpt_mask_layers_ensure(NULL, NULL, ob, NULL); + BKE_sculpt_mask_layers_ensure(nullptr, nullptr, ob, nullptr); - Mesh *mesh = ob->data; + Mesh *mesh = static_cast(ob->data); Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id); if (ob->mode == OB_MODE_SCULPT) { ED_sculpt_undo_geometry_begin(ob, op); } - BMesh *bm; const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh); - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); + BMeshCreateParams bm_create_params{}; + bm_create_params.use_toolflags = true; + BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params); - BM_mesh_bm_from_me(bm, - new_mesh, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - })); + BMeshFromMeshParams mesh_to_bm_params{}; + mesh_to_bm_params.calc_face_normal = true; + BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params); slice_paint_mask( bm, false, RNA_boolean_get(op->ptr, "fill_holes"), RNA_float_get(op->ptr, "mask_threshold")); BKE_id_free(bmain, new_mesh); - new_mesh = BKE_mesh_from_bmesh_nomain(bm, - (&(struct BMeshToMeshParams){ - .calc_object_remap = false, - }), - mesh); + BMeshToMeshParams bm_to_mesh_params{}; + bm_to_mesh_params.calc_object_remap = false; + new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh); BM_mesh_free(bm); if (RNA_boolean_get(op->ptr, "new_object")) { @@ -530,64 +519,53 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) local_view_bits = v3d->local_view_uuid; } Object *new_ob = ED_object_add_type( - C, OB_MESH, NULL, ob->loc, ob->rot, false, local_view_bits); + C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits); Mesh *new_ob_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id); const BMAllocTemplate allocsize_new_ob = BMALLOC_TEMPLATE_FROM_ME(new_ob_mesh); - bm = BM_mesh_create(&allocsize_new_ob, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); + bm = BM_mesh_create(&allocsize_new_ob, &bm_create_params); - BM_mesh_bm_from_me(bm, - new_ob_mesh, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - })); + BM_mesh_bm_from_me(bm, new_ob_mesh, &mesh_to_bm_params); slice_paint_mask(bm, true, RNA_boolean_get(op->ptr, "fill_holes"), RNA_float_get(op->ptr, "mask_threshold")); BKE_id_free(bmain, new_ob_mesh); - new_ob_mesh = BKE_mesh_from_bmesh_nomain(bm, - (&(struct BMeshToMeshParams){ - .calc_object_remap = false, - }), - mesh); + new_ob_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh); BM_mesh_free(bm); /* Remove the mask from the new object so it can be sculpted directly after slicing. */ CustomData_free_layers(&new_ob_mesh->vdata, CD_PAINT_MASK, new_ob_mesh->totvert); - BKE_mesh_nomain_to_mesh(new_ob_mesh, new_ob->data, new_ob); - BKE_mesh_copy_parameters_for_eval(new_ob->data, mesh); + Mesh *new_mesh = static_cast(new_ob->data); + BKE_mesh_nomain_to_mesh(new_ob_mesh, new_mesh, new_ob); + BKE_mesh_copy_parameters_for_eval(new_mesh, mesh); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob); - BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag(new_mesh, BKE_MESH_BATCH_DIRTY_ALL); DEG_relations_tag_update(bmain); DEG_id_tag_update(&new_ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_ob->data); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_mesh); } - BKE_mesh_nomain_to_mesh(new_mesh, ob->data, ob); + mesh = static_cast(ob->data); + BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob); if (ob->mode == OB_MODE_SCULPT) { SculptSession *ss = ob->sculpt; - ss->face_sets = CustomData_get_layer_named_for_write(&((Mesh *)ob->data)->pdata, - CD_PROP_INT32, - ".sculpt_face_set", - ((Mesh *)ob->data)->totpoly); + ss->face_sets = static_cast(CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly)); if (ss->face_sets) { /* Assign a new Face Set ID to the new faces created by the slice operation. */ - const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data); - ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id); + const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(mesh); + ED_sculpt_face_sets_initialize_none_to_id(mesh, next_face_set_id); } ED_sculpt_undo_geometry_end(ob); } - BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL); DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 533b2b43b16..cbc217fe5ae 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -768,7 +768,7 @@ static int edbm_rip_invoke__vert(bContext *C, const wmEvent *event, Object *obed if (do_fill) { /* Only needed when filling... * Also, we never want to tag best edge, - * that one won't change during split. See T44618. */ + * that one won't change during split. See #44618. */ if (larr[larr_len]->e == e_best) { BM_elem_flag_enable(larr[larr_len]->prev->e, BM_ELEM_TAG); } diff --git a/source/blender/editors/mesh/editmesh_select.cc b/source/blender/editors/mesh/editmesh_select.cc index b911da376b4..94c2e3352b3 100644 --- a/source/blender/editors/mesh/editmesh_select.cc +++ b/source/blender/editors/mesh/editmesh_select.cc @@ -5203,7 +5203,7 @@ static int verg_radial(const void *va, const void *vb) * This function leaves faces tagged which are a part of the new region. * * \note faces already tagged are ignored, to avoid finding the same regions twice: - * important when we have regions with equal face counts, see: T40309 + * important when we have regions with equal face counts, see: #40309 */ static int loop_find_regions(BMEditMesh *em, const bool selbigger) { diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index d9721db326a..78a54c97855 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -1427,7 +1427,7 @@ void MESH_OT_select_similar(wmOperatorType *ot) RNA_def_enum(ot->srna, "compare", prop_similar_compare_types, SIM_CMP_EQ, "Compare", ""); prop = RNA_def_float(ot->srna, "threshold", 0.0f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f); - /* Very small values are needed sometimes, similar area of small faces for e.g: see T87823 */ + /* Very small values are needed sometimes, similar area of small faces for e.g: see #87823 */ RNA_def_property_ui_range(prop, 0.0, 1.0, 0.01, 5); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index caa94a3f49d..2c13d09aa4f 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -849,7 +849,7 @@ static BMElem *edbm_add_edge_face_exec__tricky_extend_sel(BMesh *bm) (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) && (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) || -# if 1 /* better support mixed cases T37203. */ +# if 1 /* better support mixed cases #37203. */ ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_wire) == 1) && (edbm_add_edge_face_exec__vert_edge_lookup( @@ -5184,7 +5184,7 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op) int offset; /* Only reuse on redo because these settings need to match the current selection. - * We never want to use them on other geometry, repeat last for eg, see: T60777. */ + * We never want to use them on other geometry, repeat last for eg, see: #60777. */ if (((op->flag & OP_IS_INVOKE) || (op->flag & OP_IS_REPEAT_LAST) == 0) && RNA_property_is_set(op->ptr, prop_span)) { span = RNA_property_int_get(op->ptr, prop_span); @@ -8774,7 +8774,7 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent * } /* If we allow other tools to run, we can't be sure if they will re-allocate - * the data this operator uses, see: T68159. + * the data this operator uses, see: #68159. * Free the data here, then use #point_normals_ensure to add it back on demand. */ if (ret == OPERATOR_PASS_THROUGH) { /* Don't free on mouse-move, causes creation/freeing of the loop data in an inefficient way. */ @@ -9055,7 +9055,7 @@ static int normals_split_merge(bContext *C, const bool do_merge) BKE_editmesh_lnorspace_update(em, obedit->data); /* Note that we need temp lnor editing data for all loops of all affected vertices, since by - * setting some faces/edges as smooth we are going to change clnors spaces... See also T65809. + * setting some faces/edges as smooth we are going to change clnors spaces... See also #65809. */ BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm, true) : diff --git a/source/blender/editors/mesh/editmesh_undo.cc b/source/blender/editors/mesh/editmesh_undo.cc index 565ce28a3c1..2278a96c077 100644 --- a/source/blender/editors/mesh/editmesh_undo.cc +++ b/source/blender/editors/mesh/editmesh_undo.cc @@ -92,7 +92,7 @@ struct UndoMesh { /** \note * This isn't a perfect solution, if you edit keys and change shapes this works well - * (fixing T32442), but editing shape keys, going into object mode, removing or changing their + * (fixing #32442), but editing shape keys, going into object mode, removing or changing their * order, then go back into editmode and undo will give issues - where the old index will be * out of sync with the new object index. * @@ -156,7 +156,7 @@ static void um_arraystore_cd_compact(CustomData *cdata, * Unfortunately we can't compare dynamic layer types as they contain allocated pointers, * which burns CPU cycles looking for duplicate data that doesn't exist. * The array data isn't comparable once copied from the mesh, - * this bottlenecks on high poly meshes, see T84114. + * this bottlenecks on high poly meshes, see #84114. * * Notes: * diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index d981a9a55f7..b9cc5779139 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -294,7 +294,7 @@ void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data) Mesh *me = ob->data; BMesh *bm = me->edit_mesh->bm; - /* Workaround for T42360, 'ob->shapenr' should be 1 in this case. + /* Workaround for #42360, 'ob->shapenr' should be 1 in this case. * however this isn't synchronized between objects at the moment. */ if (UNLIKELY((ob->shapenr == 0) && (me->key && !BLI_listbase_is_empty(&me->key->block)))) { bm->shapenr = 1; @@ -958,7 +958,7 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd loop_a->e, luv_anchor, luv_next_fan, loop_b, visited, cd_loop_uv_offset); if (!result) { /* Search around `loop_a` in the opposite direction, as one of the edges may be delimited by - * a boundary, seam or disjoint UV, or itself be one of these. See: T103670, T103787. */ + * a boundary, seam or disjoint UV, or itself be one of these. See: #103670, #103787. */ const float *luv_prev_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->prev, cd_loop_uv_offset); result = seam_connected_recursive( loop_a->prev->e, luv_anchor, luv_prev_fan, loop_b, visited, cd_loop_uv_offset); @@ -1428,7 +1428,7 @@ BMEdge *EDBM_verts_mirror_get_edge(BMEditMesh *em, BMEdge *e) BMVert *v1_mirr, *v2_mirr; if ((v1_mirr = EDBM_verts_mirror_get(em, e->v1)) && (v2_mirr = EDBM_verts_mirror_get(em, e->v2)) && - /* While highly unlikely, a zero length central edges vertices can match, see T89342. */ + /* While highly unlikely, a zero length central edges vertices can match, see #89342. */ LIKELY(v1_mirr != v2_mirr)) { return BM_edge_exists(v1_mirr, v2_mirr); } @@ -1671,7 +1671,7 @@ void EDBM_update(Mesh *mesh, const struct EDBMUpdate_Params *params) } if (params->is_destructive) { - /* TODO(@campbellbarton): we may be able to remove this now! */ + /* TODO(@ideasman42): we may be able to remove this now! */ // BM_mesh_elem_table_free(em->bm, BM_ALL_NOLOOP); } else { @@ -1924,31 +1924,40 @@ void EDBM_project_snap_verts( ED_view3d_init_mats_rv3d(obedit, region->regiondata); - struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create( - CTX_data_scene(C), 0); + Scene *scene = CTX_data_scene(C); + struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create(scene, 0); + + eSnapTargetOP target_op = SCE_SNAP_TARGET_NOT_ACTIVE; + const int snap_flag = scene->toolsettings->snap_flag; + + SET_FLAG_FROM_TEST( + target_op, !(snap_flag & SCE_SNAP_TO_INCLUDE_EDITED), SCE_SNAP_TARGET_NOT_EDITED); + SET_FLAG_FROM_TEST( + target_op, !(snap_flag & SCE_SNAP_TO_INCLUDE_NONEDITED), SCE_SNAP_TARGET_NOT_NONEDITED); + SET_FLAG_FROM_TEST( + target_op, (snap_flag & SCE_SNAP_TO_ONLY_SELECTABLE), SCE_SNAP_TARGET_ONLY_SELECTABLE); BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { float mval[2], co_proj[3]; if (ED_view3d_project_float_object(region, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - if (ED_transform_snap_object_project_view3d( - snap_context, - depsgraph, - region, - CTX_wm_view3d(C), - SCE_SNAP_MODE_FACE_RAYCAST, - &(const struct SnapObjectParams){ - .snap_target_select = SCE_SNAP_TARGET_NOT_ACTIVE, - .edit_mode_type = SNAP_GEOM_FINAL, - .use_occlusion_test = true, - }, - NULL, - mval, - NULL, - NULL, - co_proj, - NULL)) { + if (ED_transform_snap_object_project_view3d(snap_context, + depsgraph, + region, + CTX_wm_view3d(C), + SCE_SNAP_MODE_FACE_RAYCAST, + &(const struct SnapObjectParams){ + .snap_target_select = target_op, + .edit_mode_type = SNAP_GEOM_FINAL, + .use_occlusion_test = true, + }, + NULL, + mval, + NULL, + NULL, + co_proj, + NULL)) { mul_v3_m4v3(eve->co, obedit->world_to_object, co_proj); } } diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index db60f253cb2..263f7164fe6 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -1260,11 +1260,6 @@ static void mesh_add_edges(Mesh *mesh, int len) mesh->totedge = totedge; - MutableSpan edges = mesh->edges_for_write(); - for (MEdge &edge : edges.take_back(len)) { - edge.flag = ME_EDGEDRAW; - } - bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter select_edge = attributes.lookup_or_add_for_write_span( ".select_edge", ATTR_DOMAIN_EDGE); diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 7386fe69b6c..856918fa365 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -296,7 +296,7 @@ void MESH_OT_smooth_normals(struct wmOperatorType *ot); void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot); void MESH_OT_flip_quad_tessellation(struct wmOperatorType *ot); -/* *** editmesh_mask_extract.c *** */ +/* *** editmesh_mask_extract.cc *** */ void MESH_OT_paint_mask_extract(struct wmOperatorType *ot); void MESH_OT_face_set_extract(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index b2cbb8c47ea..1534d2c1464 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -421,7 +421,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) /* Clear any run-time data. * Even though this mesh wont typically have run-time data, the Python API can for e.g. - * create loop-triangle cache here, which is confusing when left in the mesh, see: T90798. */ + * create loop-triangle cache here, which is confusing when left in the mesh, see: #90798. */ BKE_mesh_runtime_clear_geometry(me); /* new material indices and material array */ @@ -601,7 +601,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) /* Add back active mesh first. * This allows to keep things similar as they were, as much as possible * (i.e. data from active mesh will remain first ones in new result of the merge, - * in same order for CD layers, etc). See also T50084. + * in same order for CD layers, etc). See also #50084. */ join_mesh_single(depsgraph, bmain, diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 9515306a26c..3064f5bc96e 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -749,7 +749,7 @@ Base *ED_mball_base_and_elem_from_select_buffer(Base **bases, const uint hit_object = select_id & 0xFFFF; Base *base = NULL; MetaElem *ml = NULL; - /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ + /* TODO(@ideasman42): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index f768652824e..3bfa4167d9b 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -44,7 +44,7 @@ set(SRC object_facemap_ops.c object_gpencil_modifier.c object_hook.c - object_modes.c + object_modes.cc object_modifier.cc object_ops.c object_random.c diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index 6832e9add2c..3d24e09b53c 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -2846,7 +2846,7 @@ static Base *duplibase_for_convert( * having same 'family name' as orig ones, they will affect end result of meta-ball computation. * For until we get rid of that name-based thingy in meta-balls, that should do the trick * (this is weak, but other solution (to change name of `obn`) is even worse IMHO). - * See T65996. */ + * See #65996. */ const bool is_meta_ball = (obn->type == OB_MBALL); void *obdata = obn->data; if (is_meta_ball) { @@ -2930,7 +2930,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) /* Ensure we get all meshes calculated with a sufficient data-mask, * needed since re-evaluating single modifiers causes bugs if they depend - * on other objects data masks too, see: T50950. */ + * on other objects data masks too, see: #50950. */ { LISTBASE_FOREACH (CollectionPointerLink *, link, &selected_editable_bases) { Base *base = static_cast(link->ptr.data); @@ -2975,7 +2975,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) /* obdata already modified */ if (!IS_TAGGED(ob->data)) { /* When 2 objects with linked data are selected, converting both - * would keep modifiers on all but the converted object T26003. */ + * would keep modifiers on all but the converted object #26003. */ if (ob->type == OB_MESH) { BKE_object_free_modifiers(ob, 0); /* after derivedmesh calls! */ } @@ -3154,8 +3154,6 @@ static int object_convert_exec(bContext *C, wmOperator *op) Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH); me_eval = BKE_mesh_copy_for_eval(me_eval, false); - /* Full (edge-angle based) draw calculation should ideally be performed. */ - BKE_mesh_edges_set_draw_render(me_eval); BKE_object_material_from_eval_data(bmain, newob, &me_eval->id); Mesh *new_mesh = (Mesh *)newob->data; BKE_mesh_nomain_to_mesh(me_eval, new_mesh, newob); @@ -3710,7 +3708,7 @@ Base *ED_object_add_duplicate( ob = basen->object; - /* Link own references to the newly duplicated data T26816. + /* Link own references to the newly duplicated data #26816. * Note that this function can be called from edit-mode code, in which case we may have to * enforce remapping obdata (by default this is forbidden in edit mode). */ const int remap_flag = BKE_object_is_in_editmode(ob) ? ID_REMAP_FORCE_OBDATA_IN_EDITMODE : 0; @@ -4158,7 +4156,7 @@ static int object_join_exec(bContext *C, wmOperator *op) if (ret & OPERATOR_FINISHED) { /* Even though internally failure to invert is accounted for with a fallback, - * show a warning since the result may not be what the user expects. See T80077. + * show a warning since the result may not be what the user expects. See #80077. * * Failure to invert the matrix is typically caused by zero scaled axes * (which can be caused by constraints, even if the input scale isn't zero). diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d1473f8dd7a..ec0f48d6208 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -608,7 +608,7 @@ static bool ED_object_editmode_load_free_ex(Main *bmain, if (load_data == false) { /* Don't keep unused pose channels created by duplicating bones - * which may have been deleted/undone, see: T87631. */ + * which may have been deleted/undone, see: #87631. */ if (obedit->pose != NULL) { BKE_pose_channels_clear_with_null_bone(obedit->pose, true); } @@ -701,10 +701,10 @@ bool ED_object_editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int f if (ED_object_editmode_load_free_ex(bmain, obedit, true, free_data) == false) { /* in rare cases (background mode) its possible active object - * is flagged for editmode, without 'obedit' being set T35489. */ + * is flagged for editmode, without 'obedit' being set #35489. */ if (UNLIKELY(obedit && obedit->mode & OB_MODE_EDIT)) { obedit->mode &= ~OB_MODE_EDIT; - /* Also happens when mesh is shared across multiple objects. [#T69834] */ + /* Also happens when mesh is shared across multiple objects. #69834. */ DEG_id_tag_update(&obedit->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); } return true; @@ -789,7 +789,7 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag /* This checks actual `ob->data`, for cases when other scenes have it in edit-mode context. * Currently multiple objects sharing a mesh being in edit-mode at once isn't supported, - * see: T86767. */ + * see: #86767. */ if (BKE_object_is_in_editmode(ob)) { return true; } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b136f311557..c58ce0d8424 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -62,6 +62,11 @@ void OBJECT_OT_clear_override_library(struct wmOperatorType *ot); * Assigns to object under cursor, only first material slot. */ void OBJECT_OT_drop_named_material(struct wmOperatorType *ot); +/** + * Used for drop-box. + * Assigns to object under cursor, creates a new geometry nodes modifier. + */ +void OBJECT_OT_drop_geometry_nodes(struct wmOperatorType *ot); /** * \note Only for empty-image objects, this operator is needed */ diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.cc similarity index 92% rename from source/blender/editors/object/object_modes.c rename to source/blender/editors/object/object_modes.cc index 7e3a9dd7ccb..95b487c199d 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.cc @@ -97,7 +97,7 @@ static const char *object_mode_op_string(eObjectMode mode) if (mode == OB_MODE_SCULPT_CURVES) { return "CURVES_OT_sculptmode_toggle"; } - return NULL; + return nullptr; } bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode) @@ -160,9 +160,9 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, eObjectMode mode, Report { bool ok; if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) { - const char *opstring = object_mode_op_string(ob->mode); + const char *opstring = object_mode_op_string(eObjectMode(ob->mode)); - WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL, NULL); + WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, nullptr, nullptr); ok = ELEM(ob->mode, mode, OB_MODE_OBJECT); if (!ok) { wmOperatorType *ot = WM_operatortype_find(opstring, false); @@ -194,7 +194,7 @@ bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportL BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); - if (ob == NULL) { + if (ob == nullptr) { return (mode == OB_MODE_OBJECT); } @@ -210,13 +210,14 @@ bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportL return false; } - const char *opstring = object_mode_op_string((mode == OB_MODE_OBJECT) ? ob->mode : mode); + const char *opstring = object_mode_op_string((mode == OB_MODE_OBJECT) ? eObjectMode(ob->mode) : + mode); wmOperatorType *ot = WM_operatortype_find(opstring, false); if (!use_undo) { wm->op_undo_depth++; } - WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_REGION_WIN, NULL, NULL); + WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_REGION_WIN, nullptr, nullptr); if (!use_undo) { wm->op_undo_depth--; } @@ -232,20 +233,17 @@ bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportL bool ED_object_mode_set(bContext *C, eObjectMode mode) { /* Don't do undo push by default, since this may be called by lower level code. */ - return ED_object_mode_set_ex(C, mode, true, NULL); + return ED_object_mode_set_ex(C, mode, true, nullptr); } /** * Use for changing works-paces or changing active object. * Caller can check #OB_MODE_ALL_MODE_DATA to test if this needs to be run. */ -static bool ed_object_mode_generic_exit_ex(struct Main *bmain, - struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - bool only_test) +static bool ed_object_mode_generic_exit_ex( + Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, bool only_test) { - BLI_assert((bmain == NULL) == only_test); + BLI_assert((bmain == nullptr) == only_test); if (ob->mode & OB_MODE_EDIT) { if (BKE_object_is_in_editmode(ob)) { if (only_test) { @@ -279,7 +277,7 @@ static bool ed_object_mode_generic_exit_ex(struct Main *bmain, } } else if (ob->mode & OB_MODE_POSE) { - if (ob->pose != NULL) { + if (ob->pose != nullptr) { if (only_test) { return true; } @@ -332,7 +330,7 @@ static void ed_object_posemode_set_for_weight_paint_ex(bContext *C, const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - if (ob_arm != NULL) { + if (ob_arm != nullptr) { BKE_view_layer_synced_ensure(scene, view_layer); const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm); if (base_arm && BASE_VISIBLE(v3d, base_arm)) { @@ -387,17 +385,14 @@ void ED_object_posemode_set_for_weight_paint(bContext *C, } } -void ED_object_mode_generic_exit(struct Main *bmain, - struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob) +void ED_object_mode_generic_exit(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob) { ed_object_mode_generic_exit_ex(bmain, depsgraph, scene, ob, false); } -bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, const struct Object *ob) +bool ED_object_mode_generic_has_data(Depsgraph *depsgraph, const Object *ob) { - return ed_object_mode_generic_exit_ex(NULL, depsgraph, NULL, (Object *)ob, true); + return ed_object_mode_generic_exit_ex(nullptr, depsgraph, nullptr, (Object *)ob, true); } /** \} */ @@ -425,7 +420,7 @@ static void object_transfer_mode_reposition_view_pivot(bContext *C, const int mv Scene *scene = CTX_data_scene(C); float global_loc[3]; - if (!ED_view3d_autodist_simple(region, mval, global_loc, 0, NULL)) { + if (!ED_view3d_autodist_simple(region, mval, global_loc, 0, nullptr)) { return; } UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; @@ -446,7 +441,7 @@ static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - if (base_dst == NULL) { + if (base_dst == nullptr) { return false; } diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 5ac76b9a82c..c332c8a91fc 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -155,7 +155,7 @@ ModifierData *ED_object_modifier_add( ModifierData *md = nullptr, *new_md = nullptr; const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)type); - /* Check compatibility of modifier [T25291, T50373]. */ + /* Check compatibility of modifier [#25291, #50373]. */ if (!BKE_object_support_modifier_type_check(ob, type)) { BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2); return nullptr; @@ -675,7 +675,6 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, if (k) { medge->v1 = cvert - 1; medge->v2 = cvert; - medge->flag = ME_EDGEDRAW; medge++; } else { @@ -694,7 +693,6 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, if (k) { medge->v1 = cvert - 1; medge->v2 = cvert; - medge->flag = ME_EDGEDRAW; medge++; } else { @@ -744,7 +742,7 @@ static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src) /** * \param use_virtual_modifiers: When enabled, calculate virtual-modifiers before applying * `md_eval`. This is supported because virtual-modifiers are not modifiers from a user - * perspective, allowing shape keys to be included with the modifier being applied, see: T91923. + * perspective, allowing shape keys to be included with the modifier being applied, see: #91923. */ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, Scene *scene, @@ -985,7 +983,7 @@ static bool modifier_apply_obdata( DEG_get_evaluated_object(depsgraph, ob), md_eval, /* It's important not to apply virtual modifiers (e.g. shape-keys) because they're kept, - * causing them to be applied twice, see: T97758. */ + * causing them to be applied twice, see: #97758. */ false, true, reports); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index a73cc98c78e..c8e06ef97c7 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -262,6 +262,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_bake_image); WM_operatortype_append(OBJECT_OT_bake); WM_operatortype_append(OBJECT_OT_drop_named_material); + WM_operatortype_append(OBJECT_OT_drop_geometry_nodes); WM_operatortype_append(OBJECT_OT_unlink_data); WM_operatortype_append(OBJECT_OT_laplaciandeform_bind); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 5315e89c62d..0ceec68e0db 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -99,6 +99,8 @@ #include "ED_screen.h" #include "ED_view3d.h" +#include "MOD_nodes.h" + #include "object_intern.h" /* ------------------------------------------------------------------- */ @@ -412,7 +414,7 @@ void ED_object_parent_clear(Object *ob, const int type) } } - /* Always clear parentinv matrix for sake of consistency, see T41950. */ + /* Always clear parentinv matrix for sake of consistency, see #41950. */ unit_m4(ob->parentinv); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); @@ -460,7 +462,7 @@ void OBJECT_OT_parent_clear(wmOperatorType *ot) void ED_object_parent(Object *ob, Object *par, const int type, const char *substr) { - /* Always clear parentinv matrix for sake of consistency, see T41950. */ + /* Always clear parentinv matrix for sake of consistency, see #41950. */ unit_m4(ob->parentinv); if (!par || BKE_object_parent_loop_check(par, ob)) { @@ -582,15 +584,15 @@ bool ED_object_parent_set(ReportList *reports, /* Apply transformation of previous parenting. */ if (keep_transform) { - /* Was removed because of bug T23577, - * but this can be handy in some cases too T32616, so make optional. */ + /* Was removed because of bug #23577, + * but this can be handy in some cases too #32616, so make optional. */ BKE_object_apply_mat4(ob, ob->object_to_world, false, false); } /* Set the parent (except for follow-path constraint option). */ if (partype != PAR_PATH_CONST) { ob->parent = par; - /* Always clear parentinv matrix for sake of consistency, see T41950. */ + /* Always clear parentinv matrix for sake of consistency, see #41950. */ unit_m4(ob->parentinv); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); } @@ -1752,7 +1754,7 @@ static Collection *single_object_users_collection(Main *bmain, /* Since master collection has already be duplicated as part of scene copy, * we do not duplicate it here. * However, this means its children need to be re-added manually here, - * otherwise their parent lists are empty (which will lead to crashes, see T63101). */ + * otherwise their parent lists are empty (which will lead to crashes, see #63101). */ CollectionChild *child_next, *child = collection->children.first; CollectionChild *orig_child_last = collection->children.last; for (; child != NULL; child = child_next) { @@ -2072,7 +2074,7 @@ static void tag_localizable_objects(bContext *C, const int mode) /** * Instance indirectly referenced zero user objects, - * otherwise they're lost on reload, see T40595. + * otherwise they're lost on reload, see #40595. */ static bool make_local_all__instance_indirect_unused(Main *bmain, const Scene *scene, @@ -2725,7 +2727,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "obdata")) { single_obdata_users(bmain, scene, view_layer, v3d, flag); - /* Needed since some IDs were remapped? (incl. me->texcomesh, see T73797). */ + /* Needed since some IDs were remapped? (incl. me->texcomesh, see #73797). */ update_deps = true; } @@ -2867,6 +2869,119 @@ void OBJECT_OT_drop_named_material(wmOperatorType *ot) /** \} */ +/* ------------------------------------------------------------------- */ +/** \name Drop Geometry Nodes on Object Operator + * \{ */ + +char *ED_object_ot_drop_geometry_nodes_tooltip(bContext *C, + PointerRNA *properties, + const int mval[2]) +{ + const Object *ob = ED_view3d_give_object_under_cursor(C, mval); + if (ob == NULL) { + return BLI_strdup(""); + } + + const uint32_t session_uuid = RNA_int_get(properties, "session_uuid"); + const ID *id = BKE_libblock_find_session_uuid(CTX_data_main(C), ID_NT, session_uuid); + if (!id) { + return BLI_strdup(""); + } + + const char *tooltip = TIP_("Add modifier with node group \"%s\" on object \"%s\""); + return BLI_sprintfN(tooltip, id->name, ob->id.name); +} + +static bool check_geometry_node_group_sockets(wmOperator *op, const bNodeTree *tree) +{ + const bNodeSocket *first_input = (const bNodeSocket *)tree->inputs.first; + if (!first_input) { + BKE_report(op->reports, RPT_ERROR, "The node group must have a geometry input socket"); + return false; + } + if (first_input->type != SOCK_GEOMETRY) { + BKE_report(op->reports, RPT_ERROR, "The first input must be a geometry socket"); + return false; + } + const bNodeSocket *first_output = (const bNodeSocket *)tree->outputs.first; + if (!first_output) { + BKE_report(op->reports, RPT_ERROR, "The node group must have a geometry output socket"); + return false; + } + if (first_output->type != SOCK_GEOMETRY) { + BKE_report(op->reports, RPT_ERROR, "The first output must be a geometry socket"); + return false; + } + return true; +} + +static int drop_geometry_nodes_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *ob = ED_view3d_give_object_under_cursor(C, event->mval); + if (!ob) { + return OPERATOR_CANCELLED; + } + + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + + const uint32_t uuid = RNA_int_get(op->ptr, "session_uuid"); + bNodeTree *node_tree = (bNodeTree *)BKE_libblock_find_session_uuid(bmain, ID_NT, uuid); + if (!node_tree) { + return OPERATOR_CANCELLED; + } + if (node_tree->type != NTREE_GEOMETRY) { + BKE_report(op->reports, RPT_ERROR, "Node group must be a geometry node tree"); + return OPERATOR_CANCELLED; + } + + if (!check_geometry_node_group_sockets(op, node_tree)) { + return OPERATOR_CANCELLED; + } + + NodesModifierData *nmd = (NodesModifierData *)ED_object_modifier_add( + op->reports, bmain, scene, ob, node_tree->id.name + 2, eModifierType_Nodes); + if (!nmd) { + BKE_report(op->reports, RPT_ERROR, "Could not add geometry nodes modifier"); + return OPERATOR_CANCELLED; + } + + nmd->node_group = node_tree; + id_us_plus(&node_tree->id); + MOD_nodes_update_interface(ob, nmd); + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, NULL); + + return OPERATOR_FINISHED; +} + +/** \} */ + +void OBJECT_OT_drop_geometry_nodes(wmOperatorType *ot) +{ + ot->name = "Drop Geometry Node Group on Object"; + ot->idname = "OBJECT_OT_drop_geometry_nodes"; + + ot->invoke = drop_geometry_nodes_invoke; + ot->poll = ED_operator_view3d_active; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + PropertyRNA *prop = RNA_def_int(ot->srna, + "session_uuid", + 0, + INT32_MIN, + INT32_MAX, + "Session UUID", + "Session UUID of the geometry node group being dropped", + INT32_MIN, + INT32_MAX); + RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE)); +} + +/** \} */ + /* ------------------------------------------------------------------- */ /** \name Unlink Object Operator * \{ */ diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index ee0a07bd7be..8d085cfc92a 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -1141,7 +1141,7 @@ static int object_select_all_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } if (any_visible == false) { - /* TODO(@campbellbarton): Looks like we could remove this, + /* TODO(@ideasman42): Looks like we could remove this, * if not comment should say why its needed. */ return OPERATOR_PASS_THROUGH; } diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index 937b9aa0aa4..de4a61a829f 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -26,6 +26,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_math_matrix.hh" +#include "BLI_task.hh" #include "BLI_utildefines.h" #include "BLI_vector.hh" diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 5fbd5efa9d1..987fb545264 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -915,7 +915,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) * deform group. */ - /* TODO(@campbellbarton): This is slow in a loop, better pass def_nr directly, + /* TODO(@ideasman42): This is slow in a loop, better pass def_nr directly, * but leave for later. */ const ListBase *defbase = BKE_object_defgroup_list(ob); const int def_nr = BLI_findindex(defbase, dg); @@ -1142,7 +1142,7 @@ static void vgroup_duplicate(Object *ob) BKE_object_defgroup_active_index_set(ob, BLI_listbase_count(defbase)); icdg = BKE_object_defgroup_active_index_get(ob) - 1; - /* TODO(@campbellbarton): we might want to allow only copy selected verts here? */ + /* TODO(@ideasman42): we might want to allow only copy selected verts here? */ ED_vgroup_parray_alloc(static_cast(ob->data), &dvert_array, &dvert_tot, false); if (dvert_array) { @@ -2945,7 +2945,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) /* flags */ /* redo operator will fail in this case because vertex groups aren't stored * in local edit mode stack and toggling "all" property will lead to - * all groups deleted without way to restore them (see T29527, sergey) */ + * all groups deleted without way to restore them (see #29527, sergey) */ ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO; /* properties */ @@ -2988,7 +2988,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) /* flags */ /* redo operator will fail in this case because vertex group assignment * isn't stored in local edit mode stack and toggling "new" property will - * lead to creating plenty of new vertex groups (see T29527, sergey) */ + * lead to creating plenty of new vertex groups (see #29527, sergey) */ ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO; } @@ -3023,7 +3023,7 @@ void OBJECT_OT_vertex_group_assign_new(wmOperatorType *ot) /* flags */ /* redo operator will fail in this case because vertex group assignment * isn't stored in local edit mode stack and toggling "new" property will - * lead to creating plenty of new vertex groups (see T29527, sergey) */ + * lead to creating plenty of new vertex groups (see #29527, sergey) */ ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO; } @@ -3075,7 +3075,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) /* flags */ /* redo operator will fail in this case because vertex groups assignment * isn't stored in local edit mode stack and toggling "all" property will lead to - * removing vertices from all groups (see T29527, sergey) */ + * removing vertices from all groups (see #29527, sergey) */ ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO; /* properties */ diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index a3117f46bb9..ccee930d769 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3958,7 +3958,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance) /* blend between the current and straight position */ sub_v3_v3v3(dco, kco, co); madd_v3_v3fl(co, dco, fac); - /* keep the same distance from the root or we get glitches T35406. */ + /* keep the same distance from the root or we get glitches #35406. */ dist_ensure_v3_v3fl(co, co_root, length_accum); /* Re-use dco to compare before and after translation and add to the offset. */ diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 8c26b9caf91..846e138e958 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -676,7 +676,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) ot->exec = disconnect_hair_exec; /* flags */ - /* No REGISTER, redo does not work due to missing update, see T47750. */ + /* No REGISTER, redo does not work due to missing update, see #47750. */ ot->flag = OPTYPE_UNDO; RNA_def_boolean( @@ -978,7 +978,7 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot) ot->exec = connect_hair_exec; /* flags */ - /* No REGISTER, redo does not work due to missing update, see T47750. */ + /* No REGISTER, redo does not work due to missing update, see #47750. */ ot->flag = OPTYPE_UNDO; RNA_def_boolean(ot->srna, "all", 0, "All Hair", "Connect all hair systems to the emitter mesh"); diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index d5e55c99444..7c674728528 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -166,7 +166,7 @@ static bool fluid_validatepaths(FluidJob *job, ReportList *reports) const char *relbase = BKE_modifier_path_relbase(job->bmain, job->ob); - /* We do not accept empty paths, they can end in random places silently, see T51176. */ + /* We do not accept empty paths, they can end in random places silently, see #51176. */ if (fds->cache_directory[0] == '\0') { char cache_name[64]; BKE_fluid_cache_new_name_for_current_session(sizeof(cache_name), cache_name); diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc index 5abf5867f92..39ac4b95159 100644 --- a/source/blender/editors/render/render_internal.cc +++ b/source/blender/editors/render/render_internal.cc @@ -716,7 +716,7 @@ static void render_endjob(void *rjv) /* This render may be used again by the sequencer without the active * 'Render' where the callbacks would be re-assigned. assign dummy callbacks - * to avoid referencing freed render-jobs bug T24508. */ + * to avoid referencing freed render-jobs bug #24508. */ RE_InitRenderCB(rj->re); if (rj->main != G_MAIN) { @@ -1073,7 +1073,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even /* store actual owner of job, so modal operator could check for it, * the reason of this is that active scene could change when rendering - * several layers from compositor T31800. */ + * several layers from compositor #31800. */ op->customdata = scene; WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index 18bfad0d042..57245558f70 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -661,7 +661,7 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect rv = RE_RenderViewGetById(&rres, 0); } else { - /* possible the job clears the views but we're still drawing T45496 */ + /* possible the job clears the views but we're still drawing #45496 */ rv = nullptr; } @@ -1372,7 +1372,7 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect) scaledy = float(h); } - /* Scaling down must never assign zero width/height, see: T89868. */ + /* Scaling down must never assign zero width/height, see: #89868. */ ex = MAX2(1, short(scaledx)); ey = MAX2(1, short(scaledy)); diff --git a/source/blender/editors/render/render_shading.cc b/source/blender/editors/render/render_shading.cc index c62483daf6b..5ea01677a8e 100644 --- a/source/blender/editors/render/render_shading.cc +++ b/source/blender/editors/render/render_shading.cc @@ -216,7 +216,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* Removing material slots in edit mode screws things up, see bug T21822. */ + /* Removing material slots in edit mode screws things up, see bug #21822. */ if (ob == CTX_data_edit_object(C)) { BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode"); return OPERATOR_CANCELLED; @@ -663,7 +663,7 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot) static int material_slot_remove_unused_exec(bContext *C, wmOperator *op) { - /* Removing material slots in edit mode screws things up, see bug T21822. */ + /* Removing material slots in edit mode screws things up, see bug #21822. */ Object *ob_active = CTX_data_active_object(C); if (ob_active && BKE_object_is_in_editmode(ob_active)) { BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode"); @@ -771,7 +771,7 @@ static int new_material_exec(bContext *C, wmOperator * /*op*/) if (prop) { if (ob != nullptr) { /* Add slot follows user-preferences for creating new slots, - * RNA pointer assignment doesn't, see: T60014. */ + * RNA pointer assignment doesn't, see: #60014. */ if (BKE_object_material_get_p(ob, ob->actcol) == nullptr) { BKE_object_material_slot_add(bmain, ob); } @@ -1434,7 +1434,7 @@ static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent * /* store actual owner of job, so modal operator could check for it, * the reason of this is that active scene could change when rendering - * several layers from compositor T31800. */ + * several layers from compositor #31800. */ op->customdata = scene; WM_jobs_start(wm, wm_job); @@ -1509,7 +1509,7 @@ static int light_cache_free_exec(bContext *C, wmOperator * /*op*/) { Scene *scene = CTX_data_scene(C); - /* kill potential bake job first (see T57011) */ + /* kill potential bake job first (see #57011) */ wmWindowManager *wm = CTX_wm_manager(C); WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE); diff --git a/source/blender/editors/render/render_update.cc b/source/blender/editors/render/render_update.cc index 8aadb9edf6a..c61e26d4c7c 100644 --- a/source/blender/editors/render/render_update.cc +++ b/source/blender/editors/render/render_update.cc @@ -128,7 +128,7 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool return; } - /* Do not call if no WM available, see T42688. */ + /* Do not call if no WM available, see #42688. */ if (BLI_listbase_is_empty(&bmain->wm)) { return; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index c3df23500d4..574cefceb36 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1510,7 +1510,7 @@ static void region_rect_recursive( } /* Fix any negative dimensions. This can happen when a quad split 3d view gets too small. - * (see T72200). */ + * (see #72200). */ BLI_rcti_sanitize(®ion->winrct); quad++; @@ -1622,7 +1622,7 @@ static void area_calc_totrct(ScrArea *area, const rcti *window_rect) /* Although the following asserts are correct they lead to a very unstable Blender. * And the asserts would fail even in 2.7x * (they were added in 2.8x as part of the top-bar commit). - * For more details see T54864. */ + * For more details see #54864. */ #if 0 BLI_assert(area->totrct.xmin >= 0); BLI_assert(area->totrct.xmax >= 0); @@ -1738,7 +1738,7 @@ static void ed_default_handlers( WM_event_add_keymap_handler(®ion->handlers, keymap); } - /* Keep last because of LMB/RMB handling, see: T57527. */ + /* Keep last because of LMB/RMB handling, see: #57527. */ if (flag & ED_KEYMAP_GPENCIL) { /* grease pencil */ /* NOTE: This is now 4 keymaps - One for basic functionality, @@ -2082,7 +2082,7 @@ void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *reg if (region->flag & RGN_FLAG_HIDDEN) { WM_event_remove_handlers(C, ®ion->handlers); /* Needed to close any open pop-overs which would otherwise remain open, - * crashing on attempting to refresh. See: T93410. + * crashing on attempting to refresh. See: #93410. * * When #ED_area_init frees buttons via #UI_blocklist_free a NULL context * is passed, causing the free not to remove menus or their handlers. */ @@ -2430,7 +2430,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi * changing the header-type is jarring (especially when using Ctrl-MouseWheel). * * However, add-on install for example, forces the header to the top which shouldn't - * be applied back to the previous space type when closing - see: T57724 + * be applied back to the previous space type when closing - see: #57724 * * Newly-created windows won't have any space data, use the alignment * the space type defaults to in this case instead @@ -3362,7 +3362,7 @@ void ED_region_header_layout(const bContext *C, ARegion *region) UI_block_end(C, block); /* In most cases there is only ever one header, it never makes sense to draw more than one - * header in the same region, this results in overlapping buttons, see: T60195. */ + * header in the same region, this results in overlapping buttons, see: #60195. */ break; } @@ -3516,7 +3516,7 @@ void ED_region_info_draw_multiline(ARegion *region, /* background box */ rcti rect = *ED_region_visible_rect(region); - /* Needed in case scripts leave the font size at an unexpected value, see: T102213. */ + /* Needed in case scripts leave the font size at an unexpected value, see: #102213. */ BLF_size(fontid, style->widget.points * U.dpi_fac); /* Box fill entire width or just around text. */ diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 065cb3a61a2..384aeccfc4c 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -175,7 +175,7 @@ void ED_screen_draw_edges(wmWindow *win) if (GPU_type_matches_ex(GPU_DEVICE_INTEL_UHD, GPU_OS_UNIX, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) { /* For some reason, on linux + Intel UHD Graphics 620 the driver - * hangs if we don't flush before this. (See T57455) */ + * hangs if we don't flush before this. (See #57455) */ GPU_flush(); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 71f71dd1a5c..2ec1f499a4a 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -110,7 +110,7 @@ ScrArea *area_split(const wmWindow *win, return NULL; } - /* NOTE(@campbellbarton): regarding (fac > 0.5f) checks below. + /* NOTE(@ideasman42): regarding (fac > 0.5f) checks below. * normally it shouldn't matter which is used since the copy should match the original * however with viewport rendering and python console this isn't the case. */ @@ -377,7 +377,7 @@ static bool screen_areas_can_align(bScreen *screen, ScrArea *sa1, ScrArea *sa2, return false; } - /* Areas that are _smaller_ than minimum sizes, sharing an edge to be moved. See T100772. */ + /* Areas that are _smaller_ than minimum sizes, sharing an edge to be moved. See #100772. */ if (SCREEN_DIR_IS_VERTICAL(dir)) { const short xmin = MIN2(sa1->v1->vec.x, sa2->v1->vec.x); const short xmax = MAX2(sa1->v3->vec.x, sa2->v3->vec.x); @@ -1531,7 +1531,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const /* After we've restored back to SCREENNORMAL, we have to wait with * screen handling as it uses the area coords which aren't updated yet. * Without doing so, the screen handling gets wrong area coords, - * which in worst case can lead to crashes (see T43139) */ + * which in worst case can lead to crashes (see #43139) */ screen->skip_handling = true; } else { @@ -1555,7 +1555,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const /* Setting the area is only needed for Python scripts that call * operators in succession before returning to the main event loop. * Without this, scripts can't run any operators that require - * an area after toggling full-screen for example (see: T89526). + * an area after toggling full-screen for example (see: #89526). * NOTE: an old comment stated this was "bad code", * however it doesn't cause problems so leave as-is. */ CTX_wm_area_set(C, screen->areabase.first); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a064f4632b5..80e5da43423 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2742,7 +2742,7 @@ static void region_scale_validate_size(RegionMoveData *rmd) static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd) { /* hidden areas may have bad 'View2D.cur' value, - * correct before displaying. see T45156 */ + * correct before displaying. see #45156 */ if (rmd->region->flag & RGN_FLAG_HIDDEN) { UI_view2d_curRect_validate(&rmd->region->v2d); } @@ -3946,7 +3946,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op) rv3d->viewlock_quad = RV3D_VIEWLOCK_INIT; rv3d->viewlock = 0; - /* FIXME: This fixes missing update to workbench TAA. (see T76216) + /* FIXME: This fixes missing update to workbench TAA. (see #76216) * However, it would be nice if the tagging should be done in a more conventional way. */ rv3d->rflag |= RV3D_GPULIGHT_UPDATE; @@ -3988,7 +3988,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op) /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set, * otherwise when restoring rv3d->localvd the 'viewquat' won't - * match the 'view', set on entering localview See: T26315, + * match the 'view', set on entering localview See: #26315, * * We could avoid manipulating rv3d->localvd here if exiting * localview with a 4-split would assign these view locks */ diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 8cf11583b3a..03808acc709 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -220,7 +220,7 @@ WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindo workspace_new->order = workspace_old->order; BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids); - /* TODO(@campbellbarton): tools */ + /* TODO(@ideasman42): tools */ LISTBASE_FOREACH (WorkSpaceLayout *, layout_old, &workspace_old->layouts) { WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate( diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index a165bbaf5ef..957fb248481 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -45,15 +45,15 @@ set(SRC paint_cursor.cc paint_curve.c paint_curve_undo.c - paint_hide.c + paint_hide.cc paint_image.cc paint_image_2d.c paint_image_2d_curve_mask.cc paint_image_ops_paint.cc paint_image_proj.cc paint_mask.cc - paint_ops.c - paint_stroke.c + paint_ops.cc + paint_stroke.cc paint_utils.c paint_vertex.cc paint_vertex_color_ops.cc @@ -62,33 +62,33 @@ set(SRC paint_vertex_weight_utils.c sculpt.cc sculpt_automasking.cc - sculpt_boundary.c - sculpt_brush_types.c - sculpt_cloth.c - sculpt_detail.c + sculpt_boundary.cc + sculpt_brush_types.cc + sculpt_cloth.cc + sculpt_detail.cc sculpt_dyntopo.cc sculpt_expand.cc sculpt_face_set.cc - sculpt_filter_color.c - sculpt_filter_mask.c - sculpt_filter_mesh.c + sculpt_filter_color.cc + sculpt_filter_mask.cc + sculpt_filter_mesh.cc sculpt_geodesic.cc - sculpt_mask_expand.c - sculpt_mask_init.c - sculpt_multiplane_scrape.c - sculpt_ops.c - sculpt_paint_color.c + sculpt_mask_expand.cc + sculpt_mask_init.cc + sculpt_multiplane_scrape.cc + sculpt_ops.cc + sculpt_paint_color.cc sculpt_paint_image.cc - sculpt_pose.c - sculpt_smooth.c - sculpt_transform.c + sculpt_pose.cc + sculpt_smooth.cc + sculpt_transform.cc sculpt_undo.cc sculpt_uv.c curves_sculpt_intern.h curves_sculpt_intern.hh paint_intern.h - sculpt_intern.h + sculpt_intern.hh ) set(LIB diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc index b9e1673742e..c3d7734dd36 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc @@ -22,6 +22,8 @@ #include "BLT_translation.h" +#include "GEO_curve_constraints.hh" + /** * The code below uses a prefix naming convention to indicate the coordinate space: * cu: Local space of the curves object that is being edited. @@ -431,4 +433,40 @@ void report_invalid_uv_map(ReportList *reports) BKE_report(reports, RPT_WARNING, TIP_("Invalid UV map: UV islands must not overlap")); } +void CurvesConstraintSolver::initialize(const bke::CurvesGeometry &curves, + const IndexMask curve_selection, + const bool use_surface_collision) +{ + use_surface_collision_ = use_surface_collision; + segment_lengths_.reinitialize(curves.points_num()); + geometry::curve_constraints::compute_segment_lengths( + curves.points_by_curve(), curves.positions(), curve_selection, segment_lengths_); + if (use_surface_collision_) { + start_positions_ = curves.positions(); + } +} + +void CurvesConstraintSolver::solve_step(bke::CurvesGeometry &curves, + const IndexMask curve_selection, + const Mesh *surface, + const CurvesSurfaceTransforms &transforms) +{ + if (use_surface_collision_ && surface != nullptr) { + geometry::curve_constraints::solve_length_and_collision_constraints( + curves.points_by_curve(), + curve_selection, + segment_lengths_, + start_positions_, + *surface, + transforms, + curves.positions_for_write()); + start_positions_ = curves.positions(); + } + else { + geometry::curve_constraints::solve_length_constraints( + curves.points_by_curve(), curve_selection, segment_lengths_, curves.positions_for_write()); + } + curves.tag_positions_changed(); +} + } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 24a6a47555c..89a7d926fe9 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -66,8 +66,8 @@ class CombOperation : public CurvesSculptStrokeOperation { /** Only used when a 3D brush is used. */ CurvesBrush3D brush_3d_; - /** Length of each segment indexed by the index of the first point in the segment. */ - Array segment_lengths_cu_; + /** Solver for length and collision constraints. */ + CurvesConstraintSolver constraint_solver_; friend struct CombOperationExecutor; @@ -144,12 +144,13 @@ struct CombOperationExecutor { if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { this->initialize_spherical_brush_reference_point(); } - this->initialize_segment_lengths(); + self_->constraint_solver_.initialize( + *curves_orig_, curve_selection_, curves_id_orig_->flag & CV_SCULPT_COLLISION_ENABLED); /* Combing does nothing when there is no mouse movement, so return directly. */ return; } - EnumerableThreadSpecific> changed_curves; + Array changed_curves(curves_orig_->curves_num(), false); if (falloff_shape_ == PAINT_FALLOFF_SHAPE_TUBE) { this->comb_projected_with_symmetry(changed_curves); @@ -161,7 +162,14 @@ struct CombOperationExecutor { BLI_assert_unreachable(); } - this->restore_segment_lengths(changed_curves); + const Mesh *surface = curves_id_orig_->surface && curves_id_orig_->surface->type == OB_MESH ? + static_cast(curves_id_orig_->surface->data) : + nullptr; + + Vector indices; + const IndexMask changed_curves_mask = index_mask_ops::find_indices_from_array(changed_curves, + indices); + self_->constraint_solver_.solve_step(*curves_orig_, changed_curves_mask, surface, transforms_); curves_orig_->tag_positions_changed(); DEG_id_tag_update(&curves_id_orig_->id, ID_RECALC_GEOMETRY); @@ -172,7 +180,7 @@ struct CombOperationExecutor { /** * Do combing in screen space. */ - void comb_projected_with_symmetry(EnumerableThreadSpecific> &r_changed_curves) + void comb_projected_with_symmetry(MutableSpan r_changed_curves) { const Vector symmetry_brush_transforms = get_symmetry_brush_transforms( eCurvesSymmetryType(curves_id_orig_->symmetry)); @@ -181,8 +189,7 @@ struct CombOperationExecutor { } } - void comb_projected(EnumerableThreadSpecific> &r_changed_curves, - const float4x4 &brush_transform) + void comb_projected(MutableSpan r_changed_curves, const float4x4 &brush_transform) { const float4x4 brush_transform_inv = math::invert(brush_transform); @@ -198,7 +205,6 @@ struct CombOperationExecutor { const float brush_radius_sq_re = pow2f(brush_radius_re); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { - Vector &local_changed_curves = r_changed_curves.local(); for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; const IndexRange points = points_by_curve[curve_i]; @@ -246,7 +252,7 @@ struct CombOperationExecutor { curve_changed = true; } if (curve_changed) { - local_changed_curves.append(curve_i); + r_changed_curves[curve_i] = true; } } }); @@ -255,7 +261,7 @@ struct CombOperationExecutor { /** * Do combing in 3D space. */ - void comb_spherical_with_symmetry(EnumerableThreadSpecific> &r_changed_curves) + void comb_spherical_with_symmetry(MutableSpan r_changed_curves) { float4x4 projection; ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.ptr()); @@ -289,7 +295,7 @@ struct CombOperationExecutor { } } - void comb_spherical(EnumerableThreadSpecific> &r_changed_curves, + void comb_spherical(MutableSpan r_changed_curves, const float3 &brush_start_cu, const float3 &brush_end_cu, const float brush_radius_cu) @@ -303,7 +309,6 @@ struct CombOperationExecutor { const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { - Vector &local_changed_curves = r_changed_curves.local(); for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; const IndexRange points = points_by_curve[curve_i]; @@ -335,7 +340,7 @@ struct CombOperationExecutor { curve_changed = true; } if (curve_changed) { - local_changed_curves.append(curve_i); + r_changed_curves[curve_i] = true; } } }); @@ -357,53 +362,6 @@ struct CombOperationExecutor { self_->brush_3d_ = *brush_3d; } } - - /** - * Remember the initial length of all curve segments. This allows restoring the length after - * combing. - */ - void initialize_segment_lengths() - { - const Span positions_cu = curves_orig_->positions(); - const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); - self_->segment_lengths_cu_.reinitialize(curves_orig_->points_num()); - threading::parallel_for(curves_orig_->curves_range(), 128, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = points_by_curve[curve_i]; - for (const int point_i : points.drop_back(1)) { - const float3 &p1_cu = positions_cu[point_i]; - const float3 &p2_cu = positions_cu[point_i + 1]; - const float length_cu = math::distance(p1_cu, p2_cu); - self_->segment_lengths_cu_[point_i] = length_cu; - } - } - }); - } - - /** - * Restore previously stored length for each segment in the changed curves. - */ - void restore_segment_lengths(EnumerableThreadSpecific> &changed_curves) - { - const Span expected_lengths_cu = self_->segment_lengths_cu_; - const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); - MutableSpan positions_cu = curves_orig_->positions_for_write(); - - threading::parallel_for_each(changed_curves, [&](const Vector &changed_curves) { - threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) { - for (const int curve_i : changed_curves.as_span().slice(range)) { - const IndexRange points = points_by_curve[curve_i]; - for (const int segment_i : points.drop_back(1)) { - const float3 &p1_cu = positions_cu[segment_i]; - float3 &p2_cu = positions_cu[segment_i + 1]; - const float3 direction = math::normalize(p2_cu - p1_cu); - const float expected_length_cu = expected_lengths_cu[segment_i]; - p2_cu = p1_cu + direction * expected_length_cu; - } - } - }); - }); - } }; void CombOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index b256c4887fc..26bec5ecfa1 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -5,6 +5,7 @@ #include "BLI_enumerable_thread_specific.hh" #include "BLI_length_parameterize.hh" #include "BLI_math_matrix_types.hh" +#include "BLI_task.hh" #include "BLI_vector.hh" #include "DEG_depsgraph.h" diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index eb670d089e5..10e4d08763b 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -144,4 +144,25 @@ void report_missing_uv_map_on_original_surface(ReportList *reports); void report_missing_uv_map_on_evaluated_surface(ReportList *reports); void report_invalid_uv_map(ReportList *reports); +/** + * Utility class to make it easy for brushes to implement length preservation and surface + * collision. + */ +struct CurvesConstraintSolver { + private: + bool use_surface_collision_; + Array start_positions_; + Array segment_lengths_; + + public: + void initialize(const bke::CurvesGeometry &curves, + const IndexMask curve_selection, + const bool use_surface_collision); + + void solve_step(bke::CurvesGeometry &curves, + const IndexMask curve_selection, + const Mesh *surface, + const CurvesSurfaceTransforms &transforms); +}; + } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index a02b9d849b0..54bef8d2257 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -2,6 +2,7 @@ #include "BLI_kdtree.h" #include "BLI_rand.hh" +#include "BLI_task.hh" #include "BLI_utildefines.h" #include "BLI_vector_set.hh" @@ -965,9 +966,8 @@ static void min_distance_edit_draw(bContext *C, int /*x*/, int /*y*/, void *cust const uint pos3d = GPU_vertformat_attr_add(format3d, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); const uint col3d = GPU_vertformat_attr_add(format3d, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); - - GPU_point_size(3.0f); + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + immUniform1f("size", 4.0f); immBegin(GPU_PRIM_POINTS, points_wo.size()); float3 brush_origin_wo = math::transform_point(op_data.curves_to_world_mat, op_data.pos_cu); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc index b501f57fbf7..dc854dc166d 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc @@ -4,7 +4,9 @@ #include "curves_sculpt_intern.hh" +#include "BLI_index_mask_ops.hh" #include "BLI_math_matrix_types.hh" +#include "BLI_task.hh" #include "BLI_vector.hh" #include "PIL_time.h" @@ -41,7 +43,9 @@ namespace blender::ed::sculpt_paint { class PinchOperation : public CurvesSculptStrokeOperation { private: bool invert_pinch_; - Array segment_lengths_cu_; + + /** Solver for length and collision constraints. */ + CurvesConstraintSolver constraint_solver_; /** Only used when a 3D brush is used. */ CurvesBrush3D brush_3d_; @@ -114,8 +118,6 @@ struct PinchOperationExecutor { brush_->falloff_shape); if (stroke_extension.is_first) { - this->initialize_segment_lengths(); - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { self_->brush_3d_ = *sample_curves_3d_brush(*ctx_.depsgraph, *ctx_.region, @@ -125,6 +127,9 @@ struct PinchOperationExecutor { brush_pos_re_, brush_radius_base_re_); } + + self_->constraint_solver_.initialize( + *curves_, curve_selection_, curves_id_->flag & CV_SCULPT_COLLISION_ENABLED); } Array changed_curves(curves_->curves_num(), false); @@ -138,7 +143,14 @@ struct PinchOperationExecutor { BLI_assert_unreachable(); } - this->restore_segment_lengths(changed_curves); + Vector indices; + const IndexMask changed_curves_mask = index_mask_ops::find_indices_from_array(changed_curves, + indices); + const Mesh *surface = curves_id_->surface && curves_id_->surface->type == OB_MESH ? + static_cast(curves_id_->surface->data) : + nullptr; + self_->constraint_solver_.solve_step(*curves_, changed_curves_mask, surface, transforms_); + curves_->tag_positions_changed(); DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); @@ -269,47 +281,6 @@ struct PinchOperationExecutor { } }); } - - void initialize_segment_lengths() - { - const Span positions_cu = curves_->positions(); - const OffsetIndices points_by_curve = curves_->points_by_curve(); - self_->segment_lengths_cu_.reinitialize(curves_->points_num()); - threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { - for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = points_by_curve[curve_i]; - for (const int point_i : points.drop_back(1)) { - const float3 &p1_cu = positions_cu[point_i]; - const float3 &p2_cu = positions_cu[point_i + 1]; - const float length_cu = math::distance(p1_cu, p2_cu); - self_->segment_lengths_cu_[point_i] = length_cu; - } - } - }); - } - - void restore_segment_lengths(const Span changed_curves) - { - const Span expected_lengths_cu = self_->segment_lengths_cu_; - const OffsetIndices points_by_curve = curves_->points_by_curve(); - MutableSpan positions_cu = curves_->positions_for_write(); - - threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) { - for (const int curve_i : range) { - if (!changed_curves[curve_i]) { - continue; - } - const IndexRange points = points_by_curve[curve_i]; - for (const int segment_i : IndexRange(points.size() - 1)) { - const float3 &p1_cu = positions_cu[points[segment_i]]; - float3 &p2_cu = positions_cu[points[segment_i] + 1]; - const float3 direction = math::normalize(p2_cu - p1_cu); - const float expected_length_cu = expected_lengths_cu[points[segment_i]]; - p2_cu = p1_cu + direction * expected_length_cu; - } - } - }); - } }; void PinchOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index cb8fdf82963..26af897c0bf 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -19,8 +19,10 @@ #include "WM_api.h" +#include "BLI_index_mask_ops.hh" #include "BLI_length_parameterize.hh" #include "BLI_math_matrix.hh" +#include "BLI_task.hh" #include "GEO_add_curves_on_mesh.hh" @@ -33,8 +35,8 @@ class PuffOperation : public CurvesSculptStrokeOperation { /** Only used when a 3D brush is used. */ CurvesBrush3D brush_3d_; - /** Length of each segment indexed by the index of the first point in the segment. */ - Array segment_lengths_cu_; + /** Solver for length and collision constraints. */ + CurvesConstraintSolver constraint_solver_; friend struct PuffOperationExecutor; @@ -129,7 +131,6 @@ struct PuffOperationExecutor { BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); }); if (stroke_extension.is_first) { - this->initialize_segment_lengths(); if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { self.brush_3d_ = *sample_curves_3d_brush(*ctx_.depsgraph, *ctx_.region, @@ -139,6 +140,9 @@ struct PuffOperationExecutor { brush_pos_re_, brush_radius_base_re_); } + + self_->constraint_solver_.initialize( + *curves_, curve_selection_, curves_id_->flag & CV_SCULPT_COLLISION_ENABLED); } Array curve_weights(curve_selection_.size(), 0.0f); @@ -154,7 +158,17 @@ struct PuffOperationExecutor { } this->puff(curve_weights); - this->restore_segment_lengths(); + + Vector changed_curves_indices; + changed_curves_indices.reserve(curve_selection_.size()); + for (int64_t select_i : curve_selection_.index_range()) { + if (curve_weights[select_i] > 0.0f) { + changed_curves_indices.append(curve_selection_[select_i]); + } + } + + self_->constraint_solver_.solve_step( + *curves_, IndexMask(changed_curves_indices), surface_, transforms_); curves_->tag_positions_changed(); DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); @@ -343,44 +357,6 @@ struct PuffOperationExecutor { } }); } - - void initialize_segment_lengths() - { - const OffsetIndices points_by_curve = curves_->points_by_curve(); - const Span positions_cu = curves_->positions(); - self_->segment_lengths_cu_.reinitialize(curves_->points_num()); - threading::parallel_for(curves_->curves_range(), 128, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = points_by_curve[curve_i]; - for (const int point_i : points.drop_back(1)) { - const float3 &p1_cu = positions_cu[point_i]; - const float3 &p2_cu = positions_cu[point_i + 1]; - const float length_cu = math::distance(p1_cu, p2_cu); - self_->segment_lengths_cu_[point_i] = length_cu; - } - } - }); - } - - void restore_segment_lengths() - { - const Span expected_lengths_cu = self_->segment_lengths_cu_; - const OffsetIndices points_by_curve = curves_->points_by_curve(); - MutableSpan positions_cu = curves_->positions_for_write(); - - threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = points_by_curve[curve_i]; - for (const int segment_i : points.drop_back(1)) { - const float3 &p1_cu = positions_cu[segment_i]; - float3 &p2_cu = positions_cu[segment_i + 1]; - const float3 direction = math::normalize(p2_cu - p1_cu); - const float expected_length_cu = expected_lengths_cu[segment_i]; - p2_cu = p1_cu + direction * expected_length_cu; - } - } - }); - } }; void PuffOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index 0da162b70a8..20036994452 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -5,6 +5,7 @@ #include "curves_sculpt_intern.hh" #include "BLI_math_matrix_types.hh" +#include "BLI_task.hh" #include "BLI_vector.hh" #include "DEG_depsgraph.h" diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc index d1a21789435..d90ca26eabe 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc @@ -14,6 +14,7 @@ #include "WM_api.h" #include "BLI_enumerable_thread_specific.hh" +#include "BLI_task.hh" #include "curves_sculpt_intern.hh" diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 63535a2bbe9..a2fa4745f74 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -55,7 +55,7 @@ #include "paint_intern.h" /* still needed for sculpt_stroke_get_location, should be * removed eventually (TODO) */ -#include "sculpt_intern.h" +#include "sculpt_intern.hh" /* TODOs: * @@ -1403,7 +1403,7 @@ static void paint_update_mouse_cursor(PaintCursorContext *pcontext) { if (pcontext->win->grabcursor != 0) { /* Don't set the cursor while it's grabbed, since this will show the cursor when interacting - * with the UI (dragging a number button for e.g.), see: T102792. */ + * with the UI (dragging a number button for e.g.), see: #102792. */ return; } WM_cursor_set(pcontext->win, WM_CURSOR_PAINT); diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.cc similarity index 89% rename from source/blender/editors/sculpt_paint/paint_hide.c rename to source/blender/editors/sculpt_paint/paint_hide.cc index 2c6d3357894..6a5acfccb62 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.cc @@ -41,7 +41,7 @@ #include "paint_intern.h" /* For undo push. */ -#include "sculpt_intern.h" +#include "sculpt_intern.hh" /* Return true if the element should be hidden/shown. */ static bool is_effected(PartialVisArea area, @@ -67,21 +67,21 @@ static void partialvis_update_mesh(Object *ob, PartialVisArea area, float planes[4][4]) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); const float(*positions)[3] = BKE_pbvh_get_vert_positions(pbvh); const float *paint_mask; int totvert, i; bool any_changed = false, any_visible = false; - BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert); + BKE_pbvh_node_num_verts(pbvh, node, nullptr, &totvert); const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); - paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); + paint_mask = static_cast(CustomData_get_layer(&me->vdata, CD_PAINT_MASK)); - bool *hide_vert = CustomData_get_layer_named_for_write( - &me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert); - if (hide_vert == NULL) { - hide_vert = CustomData_add_layer_named( - &me->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totvert, ".hide_vert"); + bool *hide_vert = static_cast( + CustomData_get_layer_named_for_write(&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert)); + if (hide_vert == nullptr) { + hide_vert = static_cast(CustomData_add_layer_named( + &me->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me->totvert, ".hide_vert")); } SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); @@ -122,7 +122,7 @@ static void partialvis_update_grids(Depsgraph *depsgraph, bool any_changed = false, any_visible = false; /* Get PBVH data. */ - BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, &grids); + BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids); grid_hidden = BKE_pbvh_grid_hidden(pbvh); CCGKey key = *BKE_pbvh_get_grid_key(pbvh); @@ -147,7 +147,7 @@ static void partialvis_update_grids(Depsgraph *depsgraph, else if (action == PARTIALVIS_SHOW && area == PARTIALVIS_ALL) { /* Special case if we're showing all, just free the grid. */ MEM_freeN(gh); - grid_hidden[g] = NULL; + grid_hidden[g] = nullptr; any_changed = true; any_visible = true; continue; @@ -180,7 +180,7 @@ static void partialvis_update_grids(Depsgraph *depsgraph, /* If everything in the grid is now visible, free the grid flags. */ if (!any_hidden) { MEM_freeN(gh); - grid_hidden[g] = NULL; + grid_hidden[g] = nullptr; } } @@ -203,8 +203,9 @@ static void partialvis_update_bmesh_verts(BMesh *bm, GSetIterator gs_iter; GSET_ITER (gs_iter, verts) { - BMVert *v = BLI_gsetIterator_getKey(&gs_iter); - float *vmask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK); + BMVert *v = static_cast(BLI_gsetIterator_getKey(&gs_iter)); + float *vmask = static_cast( + CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK)); /* Hide vertex if in the hide volume. */ if (is_effected(area, planes, v->co, *vmask)) { @@ -228,7 +229,7 @@ static void partialvis_update_bmesh_faces(GSet *faces) GSetIterator gs_iter; GSET_ITER (gs_iter, faces) { - BMFace *f = BLI_gsetIterator_getKey(&gs_iter); + BMFace *f = static_cast(BLI_gsetIterator_getKey(&gs_iter)); if (paint_is_bmesh_face_hidden(f)) { BM_elem_flag_enable(f, BM_ELEM_HIDDEN); @@ -298,7 +299,7 @@ static void clip_planes_from_rect(bContext *C, static void get_pbvh_nodes( PBVH *pbvh, PBVHNode ***nodes, int *totnode, float clip_planes[4][4], PartialVisArea mode) { - BKE_pbvh_SearchCallback cb = NULL; + BKE_pbvh_SearchCallback cb = nullptr; /* Select search callback. */ switch (mode) { @@ -313,7 +314,9 @@ static void get_pbvh_nodes( break; } - PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4}; + PBVHFrustumPlanes frustum{}; + frustum.planes = clip_planes; + frustum.num_planes = 4; BKE_pbvh_search_gather(pbvh, cb, &frustum, nodes, totnode); } @@ -322,7 +325,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) ARegion *region = CTX_wm_region(C); Object *ob = CTX_data_active_object(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); PartialVisAction action; PartialVisArea area; PBVH *pbvh; @@ -333,8 +336,8 @@ static int hide_show_exec(bContext *C, wmOperator *op) int totnode; /* Read operator properties. */ - action = RNA_enum_get(op->ptr, "action"); - area = RNA_enum_get(op->ptr, "area"); + action = PartialVisAction(RNA_enum_get(op->ptr, "action")); + area = PartialVisArea(RNA_enum_get(op->ptr, "area")); rect_from_props(&rect, op->ptr); clip_planes_from_rect(C, depsgraph, clip_planes, &rect); @@ -395,7 +398,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - PartialVisArea area = RNA_enum_get(op->ptr, "area"); + PartialVisArea area = PartialVisArea(RNA_enum_get(op->ptr, "area")); if (!ELEM(area, PARTIALVIS_ALL, PARTIALVIS_MASKED)) { return WM_gesture_box_invoke(C, op, event); @@ -403,12 +406,12 @@ static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) return op->type->exec(C, op); } -void PAINT_OT_hide_show(struct wmOperatorType *ot) +void PAINT_OT_hide_show(wmOperatorType *ot) { static const EnumPropertyItem action_items[] = { {PARTIALVIS_HIDE, "HIDE", 0, "Hide", "Hide vertices"}, {PARTIALVIS_SHOW, "SHOW", 0, "Show", "Show vertices"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static const EnumPropertyItem area_items[] = { @@ -420,7 +423,7 @@ void PAINT_OT_hide_show(struct wmOperatorType *ot) 0, "Masked", "Hide or show vertices that are masked (minimum mask value of 0.5)"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* Identifiers. */ diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 9bf9f668a6b..1800f8f862b 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -1354,7 +1354,7 @@ static void uv_image_outset(const ProjPaintState *ps, len_fact = cosf(tri_ang); len_fact = UNLIKELY(len_fact < FLT_EPSILON) ? FLT_MAX : (1.0f / len_fact); - /* Clamp the length factor, see: T62236. */ + /* Clamp the length factor, see: #62236. */ len_fact = MIN2(len_fact, 10.0f); mul_v2_fl(no, ps->seam_bleed_px * len_fact); @@ -3939,7 +3939,7 @@ static void proj_paint_state_thread_init(ProjPaintState *ps, const bool reset_th ps->thread_tot = BKE_scene_num_threads(ps->scene); - /* workaround for T35057, disable threading if diameter is less than is possible for + /* workaround for #35057, disable threading if diameter is less than is possible for * optimum bucket number generation */ if (reset_threads) { ps->thread_tot = 1; @@ -5150,7 +5150,7 @@ static void copy_original_alpha_channel(ProjPixel *pixel, bool is_floatbuf) /* Use the original alpha channel data instead of the modified one */ if (is_floatbuf) { /* slightly more involved case since floats are in premultiplied space we need - * to make sure alpha is consistent, see T44627 */ + * to make sure alpha is consistent, see #44627 */ float rgb_straight[4]; premul_to_straight_v4_v4(rgb_straight, pixel->pixel.f_pt); rgb_straight[3] = pixel->origColor.f_pt[3]; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index c31ba869e7f..ee07f7cc26d 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -46,7 +46,7 @@ typedef struct CoNo { float no[3]; } CoNo; -/* paint_stroke.c */ +/* paint_stroke.cc */ typedef bool (*StrokeGetLocation)(struct bContext *C, float location[3], @@ -87,7 +87,7 @@ bool paint_supports_texture(enum ePaintMode mode); bool paint_supports_jitter(enum ePaintMode mode); /** - * Called in paint_ops.c, on each regeneration of key-maps. + * Called in paint_ops.cc, on each regeneration of key-maps. */ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf); int paint_stroke_modal(struct bContext *C, @@ -457,7 +457,7 @@ typedef enum BrushStrokeMode { BRUSH_STROKE_SMOOTH, } BrushStrokeMode; -/* paint_hide.c */ +/* paint_hide.cc */ typedef enum { PARTIALVIS_HIDE, @@ -480,7 +480,7 @@ void PAINT_OT_hide_show(struct wmOperatorType *ot); * We must thus map the modes here to the desired * eSelectOp modes. * - * Fixes T102349. + * Fixes #102349. */ typedef enum { PAINT_MASK_FLOOD_VALUE = SEL_OP_SUB, diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 177bc33bed5..bde6e25dec2 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -52,7 +52,7 @@ #include "paint_intern.h" /* For undo push. */ -#include "sculpt_intern.h" +#include "sculpt_intern.hh" static const EnumPropertyItem mode_items[] = { {PAINT_MASK_FLOOD_VALUE, @@ -1109,7 +1109,7 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext) else { /* ss->cursor_radius is only valid if the stroke started * over the sculpt mesh. If it's not we must - * compute the radius ourselves. See T81452. + * compute the radius ourselves. See #81452. */ Sculpt *sd = CTX_data_tool_settings(vc->C)->sculpt; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.cc similarity index 89% rename from source/blender/editors/sculpt_paint/paint_ops.c rename to source/blender/editors/sculpt_paint/paint_ops.cc index 06a725d703a..c7c317508dd 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.cc @@ -4,13 +4,16 @@ * \ingroup edsculpt */ +#include +#include +#include + #include "MEM_guardedalloc.h" #include "BLI_listbase.h" #include "BLI_math_vector.h" #include "BLI_string.h" #include "BLI_utildefines.h" -#include #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -41,13 +44,10 @@ #include "curves_sculpt_intern.h" #include "paint_intern.h" -#include "sculpt_intern.h" - -#include -#include +#include "sculpt_intern.hh" /* Brush operators */ -static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) +static int brush_add_exec(bContext *C, wmOperator * /*op*/) { // int type = RNA_enum_get(op->ptr, "type"); Paint *paint = BKE_paint_get_active_from_context(C); @@ -158,7 +158,7 @@ static eGPBrush_Presets gpencil_get_brush_preset_from_tool(bToolRef *tool, return GP_BRUSH_PRESET_UNKNOWN; } -static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) +static int brush_add_gpencil_exec(bContext *C, wmOperator * /*op*/) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); @@ -170,11 +170,11 @@ static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) else { /* Get the active tool to determine what type of brush is active. */ bScreen *screen = CTX_wm_screen(C); - if (screen == NULL) { + if (screen == nullptr) { return OPERATOR_CANCELLED; } - bToolRef *tool = NULL; + bToolRef *tool = nullptr; LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (area->spacetype == SPACE_VIEW3D) { /* Check the current tool is a brush. */ @@ -186,7 +186,7 @@ static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) } } - if (tool == NULL) { + if (tool == nullptr) { return OPERATOR_CANCELLED; } @@ -255,7 +255,7 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); - const bool is_gpencil = (brush && brush->gpencil_settings != NULL); + const bool is_gpencil = (brush && brush->gpencil_settings != nullptr); // Object *ob = CTX_data_active_object(C); float scalar = RNA_float_get(op->ptr, "scalar"); @@ -263,7 +263,7 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op) /* pixel radius */ { const int old_size = (!is_gpencil) ? BKE_brush_size_get(scene, brush) : brush->size; - int size = (int)(scalar * old_size); + int size = int(scalar * old_size); if (abs(old_size - size) < U.pixelsize) { if (scalar > 1) { @@ -318,7 +318,7 @@ static void BRUSH_OT_scale_size(wmOperatorType *ot) /* Palette operators */ -static int palette_new_exec(bContext *C, wmOperator *UNUSED(op)) +static int palette_new_exec(bContext *C, wmOperator * /*op*/) { Paint *paint = BKE_paint_get_active_from_context(C); Main *bmain = CTX_data_main(C); @@ -349,7 +349,7 @@ static bool palette_poll(bContext *C) { Paint *paint = BKE_paint_get_active_from_context(C); - if (paint && paint->palette != NULL && !ID_IS_LINKED(paint->palette) && + if (paint && paint->palette != nullptr && !ID_IS_LINKED(paint->palette) && !ID_IS_OVERRIDE_LIBRARY(paint->palette)) { return true; } @@ -357,7 +357,7 @@ static bool palette_poll(bContext *C) return false; } -static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op)) +static int palette_color_add_exec(bContext *C, wmOperator * /*op*/) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); @@ -401,11 +401,12 @@ static void PALETTE_OT_color_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op)) +static int palette_color_delete_exec(bContext *C, wmOperator * /*op*/) { Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = paint->palette; - PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color); + PaletteColor *color = static_cast( + BLI_findlink(&palette->colors, palette->active_color)); if (color) { BKE_palette_color_remove(palette, color); @@ -432,7 +433,7 @@ static void PALETTE_OT_color_delete(wmOperatorType *ot) static bool palette_extract_img_poll(bContext *C) { SpaceLink *sl = CTX_wm_space_data(C); - if ((sl != NULL) && (sl->spacetype == SPACE_IMAGE)) { + if ((sl != nullptr) && (sl->spacetype == SPACE_IMAGE)) { SpaceImage *sima = CTX_wm_space_image(C); Image *image = sima->image; ImageUser iuser = sima->iuser; @@ -460,11 +461,11 @@ static int palette_extract_img_exec(bContext *C, wmOperator *op) if (ibuf && ibuf->rect) { /* Extract all colors. */ - const int range = (int)pow(10.0f, threshold); + const int range = int(pow(10.0f, threshold)); for (int row = 0; row < ibuf->y; row++) { for (int col = 0; col < ibuf->x; col++) { float color[4]; - IMB_sampleImageAtLocation(ibuf, (float)col, (float)row, false, color); + IMB_sampleImageAtLocation(ibuf, float(col), float(row), false, color); for (int i = 0; i < 3; i++) { color[i] = truncf(color[i] * range) / range; } @@ -480,7 +481,7 @@ static int palette_extract_img_exec(bContext *C, wmOperator *op) } /* Free memory. */ - BLI_ghash_free(color_table, NULL, NULL); + BLI_ghash_free(color_table, nullptr, nullptr); BKE_image_release_ibuf(image, ibuf, lock); if (done) { @@ -508,7 +509,7 @@ static void PALETTE_OT_extract_from_image(wmOperatorType *ot) /* properties */ prop = RNA_def_int(ot->srna, "threshold", 1, 1, 1, "Threshold", "", 1, 1); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } /* Sort Palette color by Hue and Saturation. */ @@ -519,17 +520,17 @@ static int palette_sort_exec(bContext *C, wmOperator *op) Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = paint->palette; - if (palette == NULL) { + if (palette == nullptr) { return OPERATOR_CANCELLED; } - tPaletteColorHSV *color_array = NULL; - tPaletteColorHSV *col_elm = NULL; + tPaletteColorHSV *color_array = nullptr; + tPaletteColorHSV *col_elm = nullptr; const int totcol = BLI_listbase_count(&palette->colors); if (totcol > 0) { - color_array = MEM_calloc_arrayN(totcol, sizeof(tPaletteColorHSV), __func__); + color_array = MEM_cnew_array(totcol, __func__); /* Put all colors in an array. */ int t = 0; LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) { @@ -558,9 +559,7 @@ static int palette_sort_exec(bContext *C, wmOperator *op) } /* Clear old color swatches. */ - PaletteColor *color_next = NULL; - for (PaletteColor *color = palette->colors.first; color; color = color_next) { - color_next = color->next; + LISTBASE_FOREACH_MUTABLE (PaletteColor *, color, &palette->colors) { BKE_palette_color_remove(palette, color); } @@ -579,7 +578,7 @@ static int palette_sort_exec(bContext *C, wmOperator *op) MEM_SAFE_FREE(color_array); } - WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, nullptr); return OPERATOR_FINISHED; } @@ -591,7 +590,7 @@ static void PALETTE_OT_sort(wmOperatorType *ot) {2, "SVH", 0, "Saturation, Value, Hue", ""}, {3, "VHS", 0, "Value, Hue, Saturation", ""}, {4, "LUMINANCE", 0, "Luminance", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ @@ -614,9 +613,10 @@ static int palette_color_move_exec(bContext *C, wmOperator *op) { Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = paint->palette; - PaletteColor *palcolor = BLI_findlink(&palette->colors, palette->active_color); + PaletteColor *palcolor = static_cast( + BLI_findlink(&palette->colors, palette->active_color)); - if (palcolor == NULL) { + if (palcolor == nullptr) { return OPERATOR_CANCELLED; } @@ -625,7 +625,7 @@ static int palette_color_move_exec(bContext *C, wmOperator *op) BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */ if (BLI_listbase_link_move(&palette->colors, palcolor, direction)) { palette->active_color += direction; - WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, nullptr); } return OPERATOR_FINISHED; @@ -636,7 +636,7 @@ static void PALETTE_OT_color_move(wmOperatorType *ot) static const EnumPropertyItem slot_move[] = { {-1, "UP", 0, "Up", ""}, {1, "DOWN", 0, "Down", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ @@ -660,18 +660,18 @@ static int palette_join_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = paint->palette; - Palette *palette_join = NULL; + Palette *palette_join = nullptr; bool done = false; char name[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "palette", name); - if ((palette == NULL) || (name[0] == '\0')) { + if ((palette == nullptr) || (name[0] == '\0')) { return OPERATOR_CANCELLED; } palette_join = (Palette *)BKE_libblock_find_name(bmain, ID_PAL, name); - if (palette_join == NULL) { + if (palette_join == nullptr) { return OPERATOR_CANCELLED; } @@ -690,14 +690,12 @@ static int palette_join_exec(bContext *C, wmOperator *op) if (done) { /* Clear old color swatches. */ - PaletteColor *color_next = NULL; - for (PaletteColor *color = palette_join->colors.first; color; color = color_next) { - color_next = color->next; + LISTBASE_FOREACH_MUTABLE (PaletteColor *, color, &palette_join->colors) { BKE_palette_color_remove(palette_join, color); } /* Notifier. */ - WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, nullptr); } return OPERATOR_FINISHED; @@ -718,10 +716,10 @@ static void PALETTE_OT_join(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "palette", NULL, MAX_ID_NAME - 2, "Palette", "Name of the Palette"); + RNA_def_string(ot->srna, "palette", nullptr, MAX_ID_NAME - 2, "Palette", "Name of the Palette"); } -static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) +static int brush_reset_exec(bContext *C, wmOperator * /*op*/) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); @@ -771,8 +769,8 @@ static Brush *brush_tool_cycle(Main *bmain, Paint *paint, Brush *brush_orig, con { Brush *brush, *first_brush; - if (!brush_orig && !(brush_orig = bmain->brushes.first)) { - return NULL; + if (!brush_orig && !(brush_orig = static_cast(bmain->brushes.first))) { + return nullptr; } if (brush_tool(brush_orig, paint->runtime.tool_offset) != tool) { @@ -784,8 +782,8 @@ static Brush *brush_tool_cycle(Main *bmain, Paint *paint, Brush *brush_orig, con /* Try to tool-slot first. */ first_brush = BKE_paint_toolslots_brush_get(paint, tool); - if (first_brush == NULL) { - first_brush = bmain->brushes.first; + if (first_brush == nullptr) { + first_brush = static_cast(bmain->brushes.first); } } else { @@ -793,7 +791,8 @@ static Brush *brush_tool_cycle(Main *bmain, Paint *paint, Brush *brush_orig, con * currently active brush do a cycling via all possible * brushes with requested tool. */ - first_brush = brush_orig->id.next ? brush_orig->id.next : bmain->brushes.first; + first_brush = brush_orig->id.next ? static_cast(brush_orig->id.next) : + static_cast(bmain->brushes.first); } /* get the next brush with the active tool */ @@ -804,10 +803,11 @@ static Brush *brush_tool_cycle(Main *bmain, Paint *paint, Brush *brush_orig, con return brush; } - brush = brush->id.next ? brush->id.next : bmain->brushes.first; + brush = brush->id.next ? static_cast(brush->id.next) : + static_cast(bmain->brushes.first); } while (brush != first_brush); - return NULL; + return nullptr; } static Brush *brush_tool_toggle(Main *bmain, Paint *paint, Brush *brush_orig, const int tool) @@ -829,7 +829,7 @@ static Brush *brush_tool_toggle(Main *bmain, Paint *paint, Brush *brush_orig, co * back to the previously selected brush. */ return brush_orig->toggle_brush; } - return NULL; + return nullptr; } static bool brush_generic_tool_set(bContext *C, @@ -849,9 +849,9 @@ static bool brush_generic_tool_set(bContext *C, brush = brush_tool_cycle(bmain, paint, brush_orig, tool); } - if (((brush == NULL) && create_missing) && - ((brush_orig == NULL) || brush_tool(brush_orig, paint->runtime.tool_offset) != tool)) { - brush = BKE_brush_add(bmain, tool_name, paint->runtime.ob_mode); + if (((brush == nullptr) && create_missing) && + ((brush_orig == nullptr) || brush_tool(brush_orig, paint->runtime.tool_offset) != tool)) { + brush = BKE_brush_add(bmain, tool_name, eObjectMode(paint->runtime.ob_mode)); id_us_min(&brush->id); /* fake user only */ brush_tool_set(brush, paint->runtime.tool_offset, tool); brush->toggle_brush = brush_orig; @@ -918,7 +918,7 @@ static int brush_select_exec(bContext *C, wmOperator *op) } Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode); - if (paint == NULL) { + if (paint == nullptr) { return OPERATOR_CANCELLED; } const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode); @@ -957,34 +957,34 @@ static void PAINT_OT_brush_select(wmOperatorType *ot) prop = RNA_def_boolean( ot->srna, "toggle", 0, "Toggle", "Toggle between two brushes rather than cycling"); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); prop = RNA_def_boolean(ot->srna, "create_missing", 0, "Create Missing", "If the requested brush type does not exist, create a new brush"); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } /***** Stencil Control *****/ -typedef enum { +enum StencilControlMode { STENCIL_TRANSLATE, STENCIL_SCALE, STENCIL_ROTATE, -} StencilControlMode; +}; -typedef enum { +enum StencilTextureMode { STENCIL_PRIMARY = 0, STENCIL_SECONDARY = 1, -} StencilTextureMode; +}; -typedef enum { +enum StencilConstraint { STENCIL_CONSTRAINT_X = 1, STENCIL_CONSTRAINT_Y = 2, -} StencilConstraint; +}; -typedef struct { +struct StencilControlData { float init_mouse[2]; float init_spos[2]; float init_sdim[2]; @@ -1001,7 +1001,7 @@ typedef struct { float *rot_target; float *pos_target; short launch_event; -} StencilControlData; +}; static void stencil_set_target(StencilControlData *scd) { @@ -1039,7 +1039,7 @@ static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *ev { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); - const float mvalf[2] = {event->mval[0], event->mval[1]}; + const float mvalf[2] = {float(event->mval[0]), float(event->mval[1])}; ARegion *region = CTX_wm_region(C); StencilControlData *scd; int mask = RNA_enum_get(op->ptr, "texmode"); @@ -1055,7 +1055,7 @@ static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *ev } } - scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); + scd = static_cast(MEM_mallocN(sizeof(StencilControlData), __func__)); scd->mask = mask; scd->br = br; @@ -1063,7 +1063,7 @@ static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *ev stencil_set_target(scd); - scd->mode = RNA_enum_get(op->ptr, "mode"); + scd->mode = StencilControlMode(RNA_enum_get(op->ptr, "mode")); scd->launch_event = WM_userdef_event_type_from_keymap_type(event->type); scd->area_size[0] = region->winx; scd->area_size[1] = region->winy; @@ -1081,12 +1081,11 @@ static void stencil_restore(StencilControlData *scd) *scd->rot_target = scd->init_rot; } -static void stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) +static void stencil_control_cancel(bContext * /*C*/, wmOperator *op) { - StencilControlData *scd = op->customdata; - + StencilControlData *scd = static_cast(op->customdata); stencil_restore(scd); - MEM_freeN(op->customdata); + MEM_freeN(scd); } static void stencil_control_calculate(StencilControlData *scd, const int mval[2]) @@ -1094,7 +1093,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] #define PIXEL_MARGIN 5 float mdiff[2]; - const float mvalf[2] = {mval[0], mval[1]}; + const float mvalf[2] = {float(mval[0]), float(mval[1])}; switch (scd->mode) { case STENCIL_TRANSLATE: sub_v2_v2v2(mdiff, mvalf, scd->init_mouse); @@ -1130,10 +1129,10 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] angle = atan2f(mdiff[1], mdiff[0]); angle = scd->init_rot + angle - scd->init_angle; if (angle < 0.0f) { - angle += (float)(2 * M_PI); + angle += float(2 * M_PI); } - if (angle > (float)(2 * M_PI)) { - angle -= (float)(2 * M_PI); + if (angle > float(2 * M_PI)) { + angle -= float(2 * M_PI); } *scd->rot_target = angle; break; @@ -1144,11 +1143,11 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event) { - StencilControlData *scd = op->customdata; + StencilControlData *scd = static_cast(op->customdata); if (event->type == scd->launch_event && event->val == KM_RELEASE) { MEM_freeN(op->customdata); - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_FINISHED; } @@ -1159,7 +1158,7 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve case EVT_ESCKEY: if (event->val == KM_PRESS) { stencil_control_cancel(C, op); - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_CANCELLED; } break; @@ -1167,7 +1166,7 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve if (event->val == KM_PRESS) { if (scd->constrain_mode == STENCIL_CONSTRAINT_X) { - scd->constrain_mode = 0; + scd->constrain_mode = StencilConstraint(0); } else { scd->constrain_mode = STENCIL_CONSTRAINT_X; @@ -1179,7 +1178,7 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve case EVT_YKEY: if (event->val == KM_PRESS) { if (scd->constrain_mode == STENCIL_CONSTRAINT_Y) { - scd->constrain_mode = 0; + scd->constrain_mode = StencilConstraint(0); } else { scd->constrain_mode = STENCIL_CONSTRAINT_Y; @@ -1220,13 +1219,13 @@ static void BRUSH_OT_stencil_control(wmOperatorType *ot) {STENCIL_TRANSLATE, "TRANSLATION", 0, "Translation", ""}, {STENCIL_SCALE, "SCALE", 0, "Scale", ""}, {STENCIL_ROTATE, "ROTATION", 0, "Rotation", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static const EnumPropertyItem stencil_texture_items[] = { {STENCIL_PRIMARY, "PRIMARY", 0, "Primary", ""}, {STENCIL_SECONDARY, "SECONDARY", 0, "Secondary", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ ot->name = "Stencil Brush Control"; @@ -1244,9 +1243,9 @@ static void BRUSH_OT_stencil_control(wmOperatorType *ot) PropertyRNA *prop; prop = RNA_def_enum(ot->srna, "mode", stencil_control_items, STENCIL_TRANSLATE, "Tool", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); prop = RNA_def_enum(ot->srna, "texmode", stencil_texture_items, STENCIL_PRIMARY, "Tool", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op) @@ -1256,8 +1255,8 @@ static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op) bool use_scale = RNA_boolean_get(op->ptr, "use_scale"); bool use_repeat = RNA_boolean_get(op->ptr, "use_repeat"); bool do_mask = RNA_boolean_get(op->ptr, "mask"); - Tex *tex = NULL; - MTex *mtex = NULL; + Tex *tex = nullptr; + MTex *mtex = nullptr; if (br) { mtex = do_mask ? &br->mask_mtex : &br->mtex; tex = mtex->tex; @@ -1267,7 +1266,7 @@ static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op) float aspx, aspy; Image *ima = tex->ima; float orig_area, stencil_area, factor; - ED_image_get_uv_aspect(ima, NULL, &aspx, &aspy); + ED_image_get_uv_aspect(ima, nullptr, &aspx, &aspy); if (use_scale) { aspx *= mtex->size[0]; @@ -1300,7 +1299,7 @@ static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_FINISHED; } @@ -1355,7 +1354,7 @@ static int stencil_reset_transform_exec(bContext *C, wmOperator *op) br->mtex.rot = 0; } - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.cc similarity index 96% rename from source/blender/editors/sculpt_paint/paint_stroke.c rename to source/blender/editors/sculpt_paint/paint_stroke.cc index aa421759f17..c64751965f7 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.cc @@ -5,6 +5,9 @@ * \ingroup edsculpt */ +#include +#include + #include "MEM_guardedalloc.h" #include "BLI_listbase.h" @@ -40,10 +43,7 @@ #include "IMB_imbuf_types.h" #include "paint_intern.h" -#include "sculpt_intern.h" - -#include -#include +#include "sculpt_intern.hh" //#define DEBUG_TIME @@ -51,16 +51,16 @@ # include "PIL_time_utildefines.h" #endif -typedef struct PaintSample { +struct PaintSample { float mouse[2]; float pressure; -} PaintSample; +}; -typedef struct PaintStroke { +struct PaintStroke { void *mode_data; void *stroke_cursor; wmTimer *timer; - struct RNG *rng; + RNG *rng; /* Cached values */ ViewContext vc; @@ -124,14 +124,14 @@ typedef struct PaintStroke { StrokeDone done; bool original; /* Ray-cast original mesh at start of stroke. */ -} PaintStroke; +}; /*** Cursors ***/ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); - PaintStroke *stroke = customdata; + PaintStroke *stroke = static_cast(customdata); if (stroke && brush) { GPU_line_smooth(true); @@ -161,7 +161,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) { Paint *paint = BKE_paint_get_active_from_context(C); - PaintStroke *stroke = customdata; + PaintStroke *stroke = static_cast(customdata); GPU_line_smooth(true); @@ -175,7 +175,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); immUniform1i("colors_len", 2); /* "advanced" mode */ - const float alpha = (float)paint->paint_cursor_col[3] / 255.0f; + const float alpha = float(paint->paint_cursor_col[3]) / 255.0f; immUniform4f("color", 0.0f, 0.0f, 0.0f, alpha); immUniform4f("color2", 1.0f, 1.0f, 1.0f, alpha); immUniform1f("dash_width", 6.0f); @@ -247,7 +247,7 @@ static bool paint_stroke_use_scene_spacing(Brush *brush, ePaintMode mode) return false; } -static bool paint_tool_raycast_original(Brush *brush, ePaintMode UNUSED(mode)) +static bool paint_tool_raycast_original(Brush *brush, ePaintMode /*mode*/) { return brush->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT); } @@ -285,7 +285,7 @@ static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode m static bool paint_brush_update(bContext *C, Brush *brush, ePaintMode mode, - struct PaintStroke *stroke, + PaintStroke *stroke, const float mouse_init[2], float mouse[2], float pressure, @@ -315,18 +315,18 @@ static bool paint_brush_update(bContext *C, stroke->cached_size_pressure = pressure; ups->do_linear_conversion = false; - ups->colorspace = NULL; + ups->colorspace = nullptr; /* check here if color sampling the main brush should do color conversion. This is done here * to avoid locking up to get the image buffer during sampling */ if (brush->mtex.tex && brush->mtex.tex->type == TEX_IMAGE && brush->mtex.tex->ima) { ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf( - brush->mtex.tex->ima, &brush->mtex.tex->iuser, NULL); - if (tex_ibuf && tex_ibuf->rect_float == NULL) { + brush->mtex.tex->ima, &brush->mtex.tex->iuser, nullptr); + if (tex_ibuf && tex_ibuf->rect_float == nullptr) { ups->do_linear_conversion = true; ups->colorspace = tex_ibuf->rect_colorspace; } - BKE_image_pool_release_ibuf(brush->mtex.tex->ima, tex_ibuf, NULL); + BKE_image_pool_release_ibuf(brush->mtex.tex->ima, tex_ibuf, nullptr); } stroke->brush_init = true; @@ -394,7 +394,7 @@ static bool paint_brush_update(bContext *C, ups->anchored_size = ups->pixel_radius = sqrtf(dx * dx + dy * dy); - ups->brush_rotation = ups->brush_rotation_sec = atan2f(dx, dy) + (float)M_PI; + ups->brush_rotation = ups->brush_rotation_sec = atan2f(dx, dy) + float(M_PI); if (brush->flag & BRUSH_EDGE_TO_EDGE) { halfway[0] = dx * 0.5f + stroke->initial_mouse[0]; @@ -452,10 +452,10 @@ static bool paint_brush_update(bContext *C, } } - if ((do_random || do_random_mask) && stroke->rng == NULL) { + if ((do_random || do_random_mask) && stroke->rng == nullptr) { /* Lazy initialization. */ - uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); - rng_seed ^= (uint)POINTER_AS_INT(brush); + uint rng_seed = uint(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= uint(POINTER_AS_INT(brush)); stroke->rng = BLI_rng_new(rng_seed); } @@ -608,7 +608,7 @@ static void paint_brush_stroke_add_step( bool add_step = true; if (paint_stroke_use_dash(brush)) { int dash_samples = stroke->tot_samples % brush->dash_samples; - float dash = (float)dash_samples / (float)brush->dash_samples; + float dash = float(dash_samples) / float(brush->dash_samples); if (dash > brush->dash_ratio) { add_step = false; } @@ -692,7 +692,7 @@ static float paint_space_stroke_spacing(bContext *C, } else { /* brushes can have a minimum size of 1.0 but with pressure it can be smaller than a pixel - * causing very high step sizes, hanging blender T32381. */ + * causing very high step sizes, hanging blender #32381. */ size_clamp = max_ff(1.0f, size); } @@ -896,8 +896,8 @@ PaintStroke *paint_stroke_new(bContext *C, StrokeDone done, int event_type) { - struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke"); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + PaintStroke *stroke = MEM_cnew(__func__); ToolSettings *toolsettings = CTX_data_tool_settings(C); UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings; Paint *p = BKE_paint_get_active_from_context(C); @@ -938,7 +938,7 @@ PaintStroke *paint_stroke_new(bContext *C, * ups->average_stroke_counter to 1. */ if (ups->average_stroke_counter) { - mul_v3_fl(ups->average_stroke_accum, 1.0f / (float)ups->average_stroke_counter); + mul_v3_fl(ups->average_stroke_accum, 1.0f / float(ups->average_stroke_counter)); ups->average_stroke_counter = 1; } @@ -948,23 +948,23 @@ PaintStroke *paint_stroke_new(bContext *C, BKE_curvemapping_init(p->cavity_curve); } - BKE_paint_set_overlay_override(br->overlay_flags); + BKE_paint_set_overlay_override(eOverlayFlags(br->overlay_flags)); ups->start_pixel_radius = BKE_brush_size_get(CTX_data_scene(C), br); return stroke; } -void paint_stroke_free(bContext *C, wmOperator *UNUSED(op), PaintStroke *stroke) +void paint_stroke_free(bContext *C, wmOperator * /*op*/, PaintStroke *stroke) { RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d) { rv3d->rflag &= ~RV3D_PAINTING; } - BKE_paint_set_overlay_override(0); + BKE_paint_set_overlay_override(eOverlayFlags(0)); - if (stroke == NULL) { + if (stroke == nullptr) { return; } @@ -981,7 +981,7 @@ void paint_stroke_free(bContext *C, wmOperator *UNUSED(op), PaintStroke *stroke) } if (stroke->stroke_cursor) { - WM_paint_cursor_end(stroke->stroke_cursor); + WM_paint_cursor_end(static_cast(stroke->stroke_cursor)); } BLI_freelistN(&stroke->line); @@ -1035,7 +1035,7 @@ bool paint_space_stroke_enabled(Brush *br, ePaintMode mode) } if (mode == PAINT_MODE_SCULPT_CURVES && - !curves_sculpt_brush_uses_spacing(br->curves_sculpt_tool)) { + !curves_sculpt_brush_uses_spacing(eBrushCurvesSculptTool(br->curves_sculpt_tool))) { return false; } @@ -1130,16 +1130,16 @@ bool paint_supports_dynamic_tex_coords(Brush *br, ePaintMode mode) #define PAINT_STROKE_MODAL_CANCEL 1 -struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf) +wmKeyMap *paint_stroke_modal_keymap(wmKeyConfig *keyconf) { - static struct EnumPropertyItem modal_items[] = { + static EnumPropertyItem modal_items[] = { {PAINT_STROKE_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel and undo a stroke in progress"}, {0}}; static const char *name = "Paint Stroke Modal"; - struct wmKeyMap *keymap = WM_modalkeymap_find(keyconf, name); + wmKeyMap *keymap = WM_modalkeymap_find(keyconf, name); /* This function is called for each space-type, only needs to add map once. */ if (!keymap) { @@ -1402,17 +1402,17 @@ static void paint_stroke_line_constrain(PaintStroke *stroke, float mouse[2]) len = len_v2(line); /* divide angle by PI/4 */ - angle = 4.0f * angle / (float)M_PI; + angle = 4.0f * angle / float(M_PI); /* now take residue */ res = angle - floorf(angle); /* residue decides how close we are at a certain angle */ if (res <= 0.5f) { - angle = floorf(angle) * (float)M_PI_4; + angle = floorf(angle) * float(M_PI_4); } else { - angle = (floorf(angle) + 1.0f) * (float)M_PI_4; + angle = (floorf(angle) + 1.0f) * float(M_PI_4); } mouse[0] = stroke->constrained_pos[0] = len * cosf(angle) + stroke->last_mouse_position[0]; @@ -1440,7 +1440,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS /* see if tablet affects event. Line, anchored and drag dot strokes do not support pressure */ pressure = ((br->flag & (BRUSH_LINE | BRUSH_ANCHORED | BRUSH_DRAG_DOT)) ? 1.0f : - WM_event_tablet_data(event, &stroke->pen_flip, NULL)); + WM_event_tablet_data(event, &stroke->pen_flip, nullptr)); /* When processing a timer event the pressure from the event is 0, so use the last valid * pressure. */ @@ -1473,7 +1473,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS /* one time initialization */ if (!stroke->stroke_init) { if (paint_stroke_curve_end(C, op, stroke)) { - *stroke_p = NULL; + *stroke_p = nullptr; return OPERATOR_FINISHED; } @@ -1530,14 +1530,14 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS paint_stroke_line_constrain(stroke, mouse); paint_stroke_line_end(C, op, stroke, mouse); stroke_done(C, op, stroke); - *stroke_p = NULL; + *stroke_p = nullptr; return OPERATOR_FINISHED; } } else if (ELEM(event->type, EVT_RETKEY, EVT_SPACEKEY)) { paint_stroke_line_end(C, op, stroke, sample_average.mouse); stroke_done(C, op, stroke); - *stroke_p = NULL; + *stroke_p = nullptr; return OPERATOR_FINISHED; } else if (br->flag & BRUSH_LINE) { @@ -1650,22 +1650,22 @@ ViewContext *paint_stroke_view_context(PaintStroke *stroke) return &stroke->vc; } -void *paint_stroke_mode_data(struct PaintStroke *stroke) +void *paint_stroke_mode_data(PaintStroke *stroke) { return stroke->mode_data; } -bool paint_stroke_flipped(struct PaintStroke *stroke) +bool paint_stroke_flipped(PaintStroke *stroke) { return stroke->pen_flip; } -bool paint_stroke_inverted(struct PaintStroke *stroke) +bool paint_stroke_inverted(PaintStroke *stroke) { return stroke->stroke_mode == BRUSH_STROKE_INVERT; } -float paint_stroke_distance_get(struct PaintStroke *stroke) +float paint_stroke_distance_get(PaintStroke *stroke) { return stroke->stroke_distance; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 4469e4ca647..635331b6d6c 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -65,7 +65,7 @@ #include "bmesh.h" #include "paint_intern.h" /* own include */ -#include "sculpt_intern.h" +#include "sculpt_intern.hh" using blender::IndexRange; using namespace blender; @@ -965,7 +965,7 @@ static void do_weight_paint_vertex_single( dw->weight = weight; /* WATCH IT: take care of the ordering of applying mirror -> normalize, - * can give wrong results T26193, least confusing if normalize is done last */ + * can give wrong results #26193, least confusing if normalize is done last */ /* apply mirror */ if (index_mirr != -1) { diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index b5d3e53b00c..ebb8490276d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -68,7 +68,7 @@ #include "ED_view3d.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" @@ -325,10 +325,10 @@ float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, return iter->co; } -char SCULPT_mesh_symmetry_xyz_get(Object *object) +ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(Object *object) { const Mesh *mesh = BKE_mesh_from_object(object); - return mesh->symmetry; + return ePaintSymmetryFlags(mesh->symmetry); } /* Sculpt Face Sets and Visibility. */ @@ -1620,7 +1620,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob) /** * Disable multi-threading when dynamic-topology is enabled. Otherwise, * new entries might be inserted by #SCULPT_undo_push_node() into the #GHash - * used internally by #BM_log_original_vert_co() by a different thread. See T33787. + * used internally by #BM_log_original_vert_co() by a different thread. See #33787. */ SculptThreadedTaskData data{}; data.sd = sd; @@ -5405,7 +5405,7 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags) BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB); /* Update the object's bounding box too so that the object * doesn't get incorrectly clipped during drawing in - * draw_mesh_object(). T33790. */ + * draw_mesh_object(). #33790. */ SCULPT_update_object_bounding_box(ob); } @@ -5586,7 +5586,7 @@ static bool sculpt_stroke_test_start(bContext *C, wmOperator *op, const float mv /* Don't start the stroke until `mval` goes over the mesh. * NOTE: `mval` will only be null when re-executing the saved stroke. * We have exception for 'exec' strokes since they may not set `mval`, - * only 'location', see: T52195. */ + * only 'location', see: #52195. */ if (((op->flag & OP_IS_INVOKE) == 0) || (mval == nullptr) || over_mesh(C, op, mval)) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; @@ -5865,7 +5865,7 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) const Brush *brush = BKE_paint_brush(&sd->paint); /* XXX Canceling strokes that way does not work with dynamic topology, - * user will have to do real undo for now. See T46456. */ + * user will have to do real undo for now. See #46456. */ if (ss->cache && !SCULPT_stroke_is_dynamic_topology(ss, brush)) { paint_mesh_restore_co(sd, ob); } @@ -5893,7 +5893,7 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent * * Having blank global undo steps interleaved with sculpt steps * corrupts the DynTopo undo stack. - * See T101430. + * See #101430. * * NOTE: simply returning #OPERATOR_CANCELLED was not * sufficient to prevent this. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 6b030d8a5b7..7801741d5d8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -42,7 +42,7 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.cc similarity index 92% rename from source/blender/editors/sculpt_paint/sculpt_boundary.c rename to source/blender/editors/sculpt_paint/sculpt_boundary.cc index 967a4331ecd..bebb040fe18 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.cc @@ -23,18 +23,18 @@ #include "BKE_pbvh.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "GPU_immediate.h" #include "GPU_state.h" -#include -#include +#include +#include #define BOUNDARY_VERTEX_NONE -1 #define BOUNDARY_STEPS_NONE -1 -typedef struct BoundaryInitialVertexFloodFillData { +struct BoundaryInitialVertexFloodFillData { PBVHVertRef initial_vertex; int initial_vertex_i; int boundary_initial_vertex_steps; @@ -42,12 +42,13 @@ typedef struct BoundaryInitialVertexFloodFillData { int boundary_initial_vertex_i; int *floodfill_steps; float radius_sq; -} BoundaryInitialVertexFloodFillData; +}; static bool boundary_initial_vertex_floodfill_cb( SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { - BoundaryInitialVertexFloodFillData *data = userdata; + BoundaryInitialVertexFloodFillData *data = static_cast( + userdata); int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); @@ -91,15 +92,13 @@ static PBVHVertRef sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss SCULPT_floodfill_init(ss, &flood); SCULPT_floodfill_add_initial(&flood, initial_vertex); - BoundaryInitialVertexFloodFillData fdata = { - .initial_vertex = initial_vertex, - .boundary_initial_vertex = {BOUNDARY_VERTEX_NONE}, - .boundary_initial_vertex_steps = INT_MAX, - .radius_sq = radius * radius, - }; + BoundaryInitialVertexFloodFillData fdata{}; + fdata.initial_vertex = initial_vertex; + fdata.boundary_initial_vertex = {BOUNDARY_VERTEX_NONE}; + fdata.boundary_initial_vertex_steps = INT_MAX; + fdata.radius_sq = radius * radius; - fdata.floodfill_steps = MEM_calloc_arrayN( - SCULPT_vertex_count_get(ss), sizeof(int), "floodfill steps"); + fdata.floodfill_steps = MEM_cnew_array(SCULPT_vertex_count_get(ss), __func__); SCULPT_floodfill_execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata); SCULPT_floodfill_free(&flood); @@ -131,8 +130,8 @@ static void sculpt_boundary_index_add(SculptBoundary *boundary, boundary->verts_num++; if (boundary->verts_num >= boundary->verts_capacity) { boundary->verts_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - boundary->verts = MEM_reallocN_id( - boundary->verts, boundary->verts_capacity * sizeof(PBVHVertRef), "boundary indices"); + boundary->verts = static_cast(MEM_reallocN_id( + boundary->verts, boundary->verts_capacity * sizeof(PBVHVertRef), "boundary indices")); } }; @@ -147,9 +146,10 @@ static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, if (boundary->edges_num >= boundary->edges_capacity) { boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - boundary->edges = MEM_reallocN_id(boundary->edges, - boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge), - "boundary edges"); + boundary->edges = static_cast( + MEM_reallocN_id(boundary->edges, + boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge), + "boundary edges")); } }; @@ -196,14 +196,13 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss, /* Flood fill that adds to the boundary data all the vertices from a boundary and its duplicates. */ -typedef struct BoundaryFloodFillData { +struct BoundaryFloodFillData { SculptBoundary *boundary; GSet *included_verts; EdgeSet *preview_edges; PBVHVertRef last_visited_vertex; - -} BoundaryFloodFillData; +}; static bool boundary_floodfill_cb( SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) @@ -211,7 +210,7 @@ static bool boundary_floodfill_cb( int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - BoundaryFloodFillData *data = userdata; + BoundaryFloodFillData *data = static_cast(userdata); SculptBoundary *boundary = data->boundary; if (!SCULPT_vertex_is_boundary(ss, to_v)) { return false; @@ -236,14 +235,14 @@ static void sculpt_boundary_indices_init(SculptSession *ss, { const int totvert = SCULPT_vertex_count_get(ss); - boundary->verts = MEM_malloc_arrayN( - BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), "boundary indices"); + boundary->verts = static_cast( + MEM_malloc_arrayN(BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), __func__)); if (init_boundary_distances) { - boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances"); + boundary->distance = static_cast(MEM_calloc_arrayN(totvert, sizeof(float), __func__)); } - boundary->edges = MEM_malloc_arrayN( - BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges"); + boundary->edges = static_cast( + MEM_malloc_arrayN(BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), __func__)); GSet *included_verts = BLI_gset_int_new_ex("included verts", BOUNDARY_INDICES_BLOCK_SIZE); SculptFloodFill flood; @@ -260,12 +259,10 @@ static void sculpt_boundary_indices_init(SculptSession *ss, boundary, initial_boundary_vertex, initial_boundary_index, 0.0f, included_verts); SCULPT_floodfill_add_initial(&flood, boundary->initial_vertex); - BoundaryFloodFillData fdata = { - .boundary = boundary, - .included_verts = included_verts, - .last_visited_vertex = {BOUNDARY_VERTEX_NONE}, - - }; + BoundaryFloodFillData fdata{}; + fdata.boundary = boundary; + fdata.included_verts = included_verts; + fdata.last_visited_vertex = {BOUNDARY_VERTEX_NONE}; SCULPT_floodfill_execute(ss, &flood, boundary_floodfill_cb, &fdata); SCULPT_floodfill_free(&flood); @@ -284,7 +281,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss, SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); } - BLI_gset_free(included_verts, NULL); + BLI_gset_free(included_verts, nullptr); } /** @@ -302,8 +299,8 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; - boundary->edit_info = MEM_malloc_arrayN( - totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info"); + boundary->edit_info = static_cast( + MEM_malloc_arrayN(totvert, sizeof(SculptBoundaryEditInfo), __func__)); for (int i = 0; i < totvert; i++) { boundary->edit_info[i].original_vertex_i = BOUNDARY_VERTEX_NONE; @@ -473,7 +470,7 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, const int div = boundary_distance / radius; const float mod = fmodf(boundary_distance, radius); falloff_distance = div % 2 == 0 ? mod : radius - mod; - /* Inverts the faloff in the intervals 1 2 5 6 9 10 ... */ + /* Inverts the falloff in the intervals 1 2 5 6 9 10 ... etc. */ if (((div - 1) & 2) == 0) { direction = -1.0f; } @@ -496,7 +493,7 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object, SculptSession *ss = object->sculpt; if (initial_vertex.i == PBVH_REF_NONE) { - return NULL; + return nullptr; } SCULPT_vertex_random_access_ensure(ss); @@ -506,16 +503,16 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object, ss, initial_vertex, radius); if (boundary_initial_vertex.i == BOUNDARY_VERTEX_NONE) { - return NULL; + return nullptr; } - /* Starting from a vertex that is the limit of a boundary is ambiguous, so return NULL instead of - * forcing a random active boundary from a corner. */ + /* Starting from a vertex that is the limit of a boundary is ambiguous, so return nullptr instead + * of forcing a random active boundary from a corner. */ if (!sculpt_boundary_is_vertex_in_editable_boundary(ss, initial_vertex)) { - return NULL; + return nullptr; } - SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data"); + SculptBoundary *boundary = MEM_cnew(__func__); const bool init_boundary_distances = brush ? brush->boundary_falloff_type != BRUSH_BOUNDARY_FALLOFF_CONSTANT : @@ -548,9 +545,10 @@ void SCULPT_boundary_data_free(SculptBoundary *boundary) static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN( - totvert, sizeof(float[3]), "pivot rotation axis"); - boundary->bend.pivot_positions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "pivot positions"); + boundary->bend.pivot_rotation_axis = static_cast( + MEM_calloc_arrayN(totvert, sizeof(float[3]), __func__)); + boundary->bend.pivot_positions = static_cast( + MEM_calloc_arrayN(totvert, sizeof(float[3]), __func__)); for (int i = 0; i < totvert; i++) { if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) { @@ -588,7 +586,8 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - boundary->slide.directions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions"); + boundary->slide.directions = static_cast( + MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions")); for (int i = 0; i < totvert; i++) { if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) { @@ -614,7 +613,8 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary) { zero_v3(boundary->twist.pivot_position); - float(*poly_verts)[3] = MEM_malloc_arrayN(boundary->verts_num, sizeof(float[3]), "poly verts"); + float(*poly_verts)[3] = static_cast( + MEM_malloc_arrayN(boundary->verts_num, sizeof(float[3]), "poly verts")); for (int i = 0; i < boundary->verts_num; i++) { add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->verts[i])); copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->verts[i])); @@ -648,9 +648,9 @@ static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss, /* Deformation tasks callbacks. */ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; SculptBoundary *boundary = ss->cache->boundaries[symm_area]; @@ -707,9 +707,9 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; SculptBoundary *boundary = ss->cache->boundaries[symm_area]; @@ -758,9 +758,9 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; SculptBoundary *boundary = ss->cache->boundaries[symm_area]; @@ -809,9 +809,9 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; SculptBoundary *boundary = ss->cache->boundaries[symm_area]; @@ -857,9 +857,9 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; SculptBoundary *boundary = ss->cache->boundaries[symm_area]; @@ -916,9 +916,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int symmetry_pass = ss->cache->mirror_symmetry_pass; const SculptBoundary *boundary = ss->cache->boundaries[symmetry_pass]; @@ -978,7 +978,7 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - const int symm_area = ss->cache->mirror_symmetry_pass; + const ePaintSymmetryFlags symm_area = ss->cache->mirror_symmetry_pass; if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { PBVHVertRef initial_vertex; @@ -1024,12 +1024,11 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn return; } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc similarity index 93% rename from source/blender/editors/sculpt_paint/sculpt_brush_types.c rename to source/blender/editors/sculpt_paint/sculpt_brush_types.cc index c24bdba662a..3ae892b6a9f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc @@ -31,13 +31,13 @@ #include "ED_view3d.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "bmesh.h" -#include -#include -#include +#include +#include +#include /* -------------------------------------------------------------------- */ /** \name SculptProjectVector @@ -45,13 +45,12 @@ * Fast-path for #project_plane_v3_v3v3 * \{ */ -typedef struct SculptProjectVector { +struct SculptProjectVector { float plane[3]; float len_sq; float len_sq_inv_neg; bool is_valid; - -} SculptProjectVector; +}; static bool plane_point_side_flip(const float co[3], const float plane[4], const bool flip) { @@ -239,7 +238,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *offset = data->offset; @@ -305,13 +304,12 @@ void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .offset = offset, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.offset = offset; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -328,7 +326,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *area_no = data->area_no; @@ -416,14 +414,13 @@ void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) mul_v3_fl(temp, displace); add_v3_v3(area_co, temp); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no = area_no, - .area_co = area_co, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.area_no = area_no; + data.area_co = area_co; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -434,7 +431,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *area_no = data->area_no; @@ -521,14 +518,13 @@ void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod mul_v3_fl(temp, displace); add_v3_v3(area_co, temp); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no = area_no, - .area_co = area_co, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.area_no = area_no; + data.area_co = area_co; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -545,7 +541,7 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; float(*mat)[4] = data->mat; @@ -700,16 +696,15 @@ void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to float clay_strength = ss->cache->bstrength * SCULPT_clay_thumb_get_stabilized_pressure(ss->cache); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no_sp = area_no_sp, - .area_co = ss->cache->location, - .mat = mat, - .clay_strength = clay_strength, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.area_no_sp = area_no_sp; + data.area_co = ss->cache->location; + data.mat = mat; + data.clay_strength = clay_strength; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -726,7 +721,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *area_no = data->area_no; @@ -808,14 +803,13 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno mul_v3_fl(temp, displace); add_v3_v3(area_co, temp); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no = area_no, - .area_co = area_co, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.area_no = area_no; + data.area_co = area_co; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -828,18 +822,18 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno /** \name Sculpt Clay Brush * \{ */ -typedef struct ClaySampleData { +struct ClaySampleData { float plane_dist[2]; -} ClaySampleData; +}; static void calc_clay_surface_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; - ClaySampleData *csd = tls->userdata_chunk; + ClaySampleData *csd = static_cast(tls->userdata_chunk); const float *area_no = data->area_no; const float *area_co = data->area_co; float plane[4]; @@ -877,12 +871,12 @@ static void calc_clay_surface_task_cb(void *__restrict userdata, } } -static void calc_clay_surface_reduce(const void *__restrict UNUSED(userdata), +static void calc_clay_surface_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - ClaySampleData *join = chunk_join; - ClaySampleData *csd = chunk; + ClaySampleData *join = static_cast(chunk_join); + ClaySampleData *csd = static_cast(chunk); join->plane_dist[0] = MIN2(csd->plane_dist[0], join->plane_dist[0]); join->plane_dist[1] = MIN2(csd->plane_dist[1], join->plane_dist[1]); } @@ -891,7 +885,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *area_no = data->area_no; @@ -965,15 +959,14 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); - SculptThreadedTaskData sample_data = { - .sd = NULL, - .ob = ob, - .brush = brush, - .nodes = nodes, - .totnode = totnode, - .area_no = area_no, - .area_co = ss->cache->location, - }; + SculptThreadedTaskData sample_data{}; + sample_data.sd = nullptr; + sample_data.ob = ob; + sample_data.brush = brush; + sample_data.nodes = nodes; + sample_data.totnode = totnode; + sample_data.area_no = area_no; + sample_data.area_co = ss->cache->location; ClaySampleData csd = {{0}}; @@ -999,14 +992,13 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) copy_v3_v3(area_co, ss->cache->location); add_v3_v3(area_co, temp); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no = area_no, - .area_co = area_co, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.area_no = area_no; + data.area_co = area_co; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1017,7 +1009,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; float(*mat)[4] = data->mat; @@ -1060,7 +1052,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, SCULPT_automasking_node_update(ss, &automask_data, &vd); - /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */ + /* The normal from the vertices is ignored, it causes glitch with planes, see: #44390. */ const float fade = bstrength * SCULPT_brush_strength_factor(ss, brush, vd.co, @@ -1159,15 +1151,14 @@ void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t invert_m4_m4(mat, tmat); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no_sp = area_no_sp, - .area_co = area_co, - .mat = mat, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.area_no_sp = area_no_sp; + data.area_co = area_co; + data.mat = mat; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1178,7 +1169,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; SculptProjectVector *spvc = data->spvc; @@ -1314,14 +1305,13 @@ void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to sculpt_project_v3_cache_init(&spvc, grab_delta); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .spvc = &spvc, - .grab_delta = grab_delta, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.spvc = &spvc; + data.grab_delta = grab_delta; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1332,7 +1322,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *cono = data->cono; @@ -1368,7 +1358,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, orig_data.co, sqrtf(test.dist), orig_data.no, - NULL, + nullptr, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, @@ -1395,13 +1385,12 @@ void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta); cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .cono = cono, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.cono = cono; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1412,7 +1401,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float angle = data->angle; @@ -1450,7 +1439,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, orig_data.co, sqrtf(test.dist), orig_data.no, - NULL, + nullptr, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, @@ -1477,13 +1466,12 @@ void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod static const int flip[8] = {1, -1, -1, 1, -1, 1, 1, -1}; const float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass]; - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .angle = angle, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.angle = angle; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1494,7 +1482,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; Sculpt *sd = data->sd; const Brush *brush = data->brush; @@ -1598,17 +1586,16 @@ void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - if (ss->cache->layer_displacement_factor == NULL) { - ss->cache->layer_displacement_factor = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss), - "layer displacement factor"); + if (ss->cache->layer_displacement_factor == nullptr) { + ss->cache->layer_displacement_factor = MEM_cnew_array(SCULPT_vertex_count_get(ss), + __func__); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1619,7 +1606,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; @@ -1677,12 +1664,11 @@ void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno { Brush *brush = BKE_paint_brush(&sd->paint); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1693,7 +1679,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *cono = data->cono; @@ -1751,13 +1737,12 @@ void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta); cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .cono = cono, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.cono = cono; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1777,7 +1762,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; SculptProjectVector *spvc = data->spvc; @@ -1878,15 +1863,14 @@ void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod sculpt_project_v3_cache_init(&spvc, ss->cache->sculpt_normal_symm); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .spvc = &spvc, - .offset = offset, - .flippedbstrength = flippedbstrength, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.spvc = &spvc; + data.offset = offset; + data.flippedbstrength = flippedbstrength; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -1897,7 +1881,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; float(*stroke_xz)[3] = data->stroke_xz; @@ -2001,13 +1985,12 @@ void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode normalize_v3_v3(stroke_xz[0], mat[0]); normalize_v3_v3(stroke_xz[1], mat[2]); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .stroke_xz = stroke_xz, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.stroke_xz = stroke_xz; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2018,7 +2001,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *grab_delta = data->grab_delta; @@ -2056,7 +2039,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, orig_data.co, sqrtf(test.dist), orig_data.no, - NULL, + nullptr, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, @@ -2094,13 +2077,12 @@ void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .grab_delta = grab_delta, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.grab_delta = grab_delta; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2109,9 +2091,9 @@ void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *grab_delta = data->grab_delta; @@ -2209,13 +2191,12 @@ void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .grab_delta = grab_delta, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.grab_delta = grab_delta; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2232,7 +2213,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float *offset = data->offset; @@ -2267,7 +2248,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, orig_data.co, sqrtf(test.dist), orig_data.no, - NULL, + nullptr, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, @@ -2301,13 +2282,12 @@ void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .offset = offset, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.offset = offset; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2324,7 +2304,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; @@ -2357,7 +2337,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, orig_data.co, sqrtf(test.dist), orig_data.no, - NULL, + nullptr, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, @@ -2488,7 +2468,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = ss->cache->bstrength; @@ -2521,7 +2501,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, orig_data.co, sqrtf(test.dist), orig_data.no, - NULL, + nullptr, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, @@ -2546,12 +2526,11 @@ void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t BKE_curvemapping_init(brush->curve); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2576,7 +2555,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f); @@ -2629,12 +2608,11 @@ void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **node BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2651,7 +2629,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f); @@ -2743,9 +2721,9 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, } static void do_displacement_smear_store_prev_disp_task_cb_ex( - void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) + void *__restrict userdata, const int n, const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHVertexIter vd; @@ -2766,9 +2744,10 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes const int totvert = SCULPT_vertex_count_get(ss); if (!ss->cache->prev_displacement) { - ss->cache->prev_displacement = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "prev displacement"); - ss->cache->limit_surface_co = MEM_malloc_arrayN(totvert, sizeof(float[3]), "limit surface co"); + ss->cache->prev_displacement = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__)); + ss->cache->limit_surface_co = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__)); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -2779,12 +2758,11 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes } } /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2803,7 +2781,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; Sculpt *sd = data->sd; const Brush *brush = data->brush; @@ -2885,13 +2863,13 @@ void SCULPT_bmesh_topology_rake( for (iteration = 0; iteration <= count; iteration++) { - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .strength = factor, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.strength = factor; + TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -2909,7 +2887,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = ss->cache->bstrength; @@ -2958,12 +2936,11 @@ void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot Brush *brush = BKE_paint_brush(&sd->paint); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.cc similarity index 90% rename from source/blender/editors/sculpt_paint/sculpt_cloth.c rename to source/blender/editors/sculpt_paint/sculpt_cloth.cc index a5c469ca3a0..3ceab5431ec 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.cc @@ -35,7 +35,7 @@ #include "WM_api.h" #include "WM_types.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" @@ -49,9 +49,9 @@ #include "bmesh.h" -#include -#include -#include +#include +#include +#include static void cloth_brush_simulation_location_get(SculptSession *ss, const Brush *brush, @@ -75,30 +75,28 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, { BLI_assert(ss->cache); BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH); - PBVHNode **nodes = NULL; + PBVHNode **nodes = nullptr; switch (brush->cloth_simulation_area_type) { case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: { - SculptSearchSphereData data = { - .ss = ss, - .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), - .original = false, - .ignore_fully_ineffective = false, - .center = ss->cache->initial_location, - }; + SculptSearchSphereData data{}; + data.ss = ss; + data.radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)); + data.original = false; + data.ignore_fully_ineffective = false; + data.center = ss->cache->initial_location; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); } break; case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL: - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, r_totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, r_totnode); break; case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: { - SculptSearchSphereData data = { - .ss = ss, - .radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)), - .original = false, - .ignore_fully_ineffective = false, - .center = ss->cache->location, - }; + SculptSearchSphereData data{}; + data.ss = ss; + data.radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)); + data.original = false; + data.ignore_fully_ineffective = false; + data.center = ss->cache->location; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); } break; } @@ -159,10 +157,10 @@ static void cloth_brush_reallocate_constraints(SculptClothSimulation *cloth_sim) { if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) { cloth_sim->capacity_length_constraints += CLOTH_LENGTH_CONSTRAINTS_BLOCK; - cloth_sim->length_constraints = MEM_reallocN_id(cloth_sim->length_constraints, - cloth_sim->capacity_length_constraints * - sizeof(SculptClothLengthConstraint), - "length constraints"); + cloth_sim->length_constraints = static_cast(MEM_reallocN_id( + cloth_sim->length_constraints, + cloth_sim->capacity_length_constraints * sizeof(SculptClothLengthConstraint), + "length constraints")); } } @@ -289,10 +287,11 @@ static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_ cloth_brush_reallocate_constraints(cloth_sim); } -static void do_cloth_brush_build_constraints_task_cb_ex( - void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) +static void do_cloth_brush_build_constraints_task_cb_ex(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; PBVHNode *node = data->nodes[n]; @@ -305,16 +304,16 @@ static void do_cloth_brush_build_constraints_task_cb_ex( PBVHVertexIter vd; - const bool pin_simulation_boundary = ss->cache != NULL && brush != NULL && + const bool pin_simulation_boundary = ss->cache != nullptr && brush != nullptr && brush->flag2 & BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY && brush->cloth_simulation_area_type != BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC; - const bool use_persistent = brush != NULL && brush->flag & BRUSH_PERSISTENT; + const bool use_persistent = brush != nullptr && brush->flag & BRUSH_PERSISTENT; - /* Brush can be NULL in tools that use the solver without relying of constraints with deformation - * positions. */ - const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL && + /* Brush can be nullptr in tools that use the solver without relying of constraints with + * deformation positions. */ + const bool cloth_is_deform_brush = ss->cache != nullptr && brush != nullptr && SCULPT_is_cloth_deform_brush(brush); const bool use_falloff_plane = brush->cloth_force_falloff_type == @@ -417,7 +416,7 @@ static void do_cloth_brush_build_constraints_task_cb_ex( BKE_pbvh_vertex_iter_end; } -static void cloth_brush_apply_force_to_vertex(SculptSession *UNUSED(ss), +static void cloth_brush_apply_force_to_vertex(SculptSession * /*ss*/, SculptClothSimulation *cloth_sim, const float force[3], const int vertex_index) @@ -429,7 +428,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; SculptClothSimulation *cloth_sim = ss->cache->cloth_sim; @@ -589,7 +588,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *depsgraph) { - ListBase *cache = NULL; + ListBase *cache = nullptr; DEGObjectIterSettings deg_iter_settings = {0}; deg_iter_settings.depsgraph = depsgraph; deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | @@ -608,11 +607,11 @@ static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *de if (!cmd->bvhtree) { continue; } - if (cache == NULL) { - cache = MEM_callocN(sizeof(ListBase), "ColliderCache array"); + if (cache == nullptr) { + cache = MEM_cnew(__func__); } - ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache"); + ColliderCache *col = MEM_cnew(__func__); col->ob = ob; col->collmd = cmd; collision_move_object(cmd, 1.0, 0.0, true); @@ -622,10 +621,10 @@ static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *de return cache; } -typedef struct ClothBrushCollision { +struct ClothBrushCollision { CollisionModifierData *col_data; - struct IsectRayPrecalc isect_precalc; -} ClothBrushCollision; + IsectRayPrecalc isect_precalc; +}; static void cloth_brush_collision_cb(void *userdata, int index, @@ -644,7 +643,7 @@ static void cloth_brush_collision_cb(void *userdata, float dist = 0.0f; bool tri_hit = isect_ray_tri_watertight_v3( - ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, NULL); + ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, nullptr); normal_tri_v3(no, UNPACK3(tri)); madd_v3_v3v3fl(co, ray->origin, ray->direction, dist); @@ -669,7 +668,8 @@ static void cloth_brush_solve_collision(Object *object, float obmat_inv[4][4]; invert_m4_m4(obmat_inv, object->object_to_world); - for (collider_cache = cloth_sim->collider_list->first; collider_cache; + for (collider_cache = static_cast(cloth_sim->collider_list->first); + collider_cache; collider_cache = collider_cache->next) { float ray_start[3], ray_normal[3]; float pos_world_space[3], prev_pos_world_space[3]; @@ -720,10 +720,11 @@ static void cloth_brush_solve_collision(Object *object, } } -static void do_cloth_brush_solve_simulation_task_cb_ex( - void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) +static void do_cloth_brush_solve_simulation_task_cb_ex(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; @@ -771,7 +772,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v); madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v); - if (cloth_sim->collider_list != NULL) { + if (cloth_sim->collider_list != nullptr) { cloth_brush_solve_collision(data->ob, cloth_sim, i); } @@ -910,14 +911,13 @@ void SCULPT_cloth_brush_do_simulation_step( cloth_brush_satisfy_constraints(ss, brush, cloth_sim); /* Solve the simulation and write the final step to the mesh. */ - SculptThreadedTaskData solve_simulation_data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .cloth_time_step = CLOTH_SIMULATION_TIME_STEP, - .cloth_sim = cloth_sim, - }; + SculptThreadedTaskData solve_simulation_data{}; + solve_simulation_data.sd = sd; + solve_simulation_data.ob = ob; + solve_simulation_data.brush = brush; + solve_simulation_data.nodes = nodes; + solve_simulation_data.cloth_time_step = CLOTH_SIMULATION_TIME_STEP; + solve_simulation_data.cloth_sim = cloth_sim; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -937,15 +937,14 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod float imat[4][4]; float offset[3]; - SculptThreadedTaskData apply_forces_data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .area_no = area_no, - .area_co = area_co, - .mat = imat, - }; + SculptThreadedTaskData apply_forces_data{}; + apply_forces_data.sd = sd; + apply_forces_data.ob = ob; + apply_forces_data.brush = brush; + apply_forces_data.nodes = nodes; + apply_forces_data.area_no = area_no; + apply_forces_data.area_co = area_co; + apply_forces_data.mat = imat; BKE_curvemapping_init(brush->curve); @@ -1016,10 +1015,10 @@ static void cloth_sim_initialize_default_node_state(SculptSession *ss, { PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - cloth_sim->node_state = MEM_malloc_arrayN( - totnode, sizeof(eSculptClothNodeSimState), "node sim state"); + cloth_sim->node_state = static_cast( + MEM_malloc_arrayN(totnode, sizeof(eSculptClothNodeSimState), "node sim state")); cloth_sim->node_state_index = BLI_ghash_ptr_new("node sim state indices"); for (int i = 0; i < totnode; i++) { cloth_sim->node_state[i] = SCULPT_CLOTH_NODE_UNINITIALIZED; @@ -1039,34 +1038,27 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob, const int totverts = SCULPT_vertex_count_get(ss); SculptClothSimulation *cloth_sim; - cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints"); + cloth_sim = MEM_cnew(__func__); - cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) * - CLOTH_LENGTH_CONSTRAINTS_BLOCK, - "cloth length constraints"); + cloth_sim->length_constraints = MEM_cnew_array( + CLOTH_LENGTH_CONSTRAINTS_BLOCK, __func__); cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK; - cloth_sim->acceleration = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim acceleration"); - cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos"); - cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos"); - cloth_sim->last_iteration_pos = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim last iteration pos"); - cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos"); - cloth_sim->init_no = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init normals"); - cloth_sim->length_constraint_tweak = MEM_calloc_arrayN( - totverts, sizeof(float), "cloth sim length tweak"); + cloth_sim->acceleration = MEM_cnew_array(totverts, __func__); + cloth_sim->pos = MEM_cnew_array(totverts, __func__); + cloth_sim->prev_pos = MEM_cnew_array(totverts, __func__); + cloth_sim->last_iteration_pos = MEM_cnew_array(totverts, __func__); + cloth_sim->init_pos = MEM_cnew_array(totverts, __func__); + cloth_sim->init_no = MEM_cnew_array(totverts, __func__); + cloth_sim->length_constraint_tweak = MEM_cnew_array(totverts, __func__); if (needs_deform_coords) { - cloth_sim->deformation_pos = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim deformation positions"); - cloth_sim->deformation_strength = MEM_calloc_arrayN( - totverts, sizeof(float), "cloth sim deformation strength"); + cloth_sim->deformation_pos = MEM_cnew_array(totverts, __func__); + cloth_sim->deformation_strength = MEM_cnew_array(totverts, __func__); } if (cloth_softbody_strength > 0.0f) { - cloth_sim->softbody_pos = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim softbody pos"); + cloth_sim->softbody_pos = MEM_cnew_array(totverts, __func__); } cloth_sim->mass = cloth_mass; @@ -1104,15 +1096,15 @@ void SCULPT_cloth_brush_ensure_nodes_constraints( cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints"); - SculptThreadedTaskData build_constraints_data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .cloth_sim = cloth_sim, - .cloth_sim_initial_location = initial_location, - .cloth_sim_radius = radius, - }; + SculptThreadedTaskData build_constraints_data{}; + build_constraints_data.sd = sd; + build_constraints_data.ob = ob; + build_constraints_data.brush = brush; + build_constraints_data.nodes = nodes; + build_constraints_data.cloth_sim = cloth_sim; + build_constraints_data.cloth_sim_initial_location = initial_location; + build_constraints_data.cloth_sim_radius = radius; + BLI_task_parallel_range( 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); @@ -1122,8 +1114,8 @@ void SCULPT_cloth_brush_ensure_nodes_constraints( void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim) { const int totverts = SCULPT_vertex_count_get(ss); - const bool has_deformation_pos = cloth_sim->deformation_pos != NULL; - const bool has_softbody_pos = cloth_sim->softbody_pos != NULL; + const bool has_deformation_pos = cloth_sim->deformation_pos != nullptr; + const bool has_softbody_pos = cloth_sim->softbody_pos != nullptr; for (int i = 0; i < totverts; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -1232,7 +1224,7 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); } -void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim) +void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim) { MEM_SAFE_FREE(cloth_sim->pos); MEM_SAFE_FREE(cloth_sim->last_iteration_pos); @@ -1246,7 +1238,7 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim) MEM_SAFE_FREE(cloth_sim->init_no); MEM_SAFE_FREE(cloth_sim->deformation_strength); MEM_SAFE_FREE(cloth_sim->node_state); - BLI_ghash_free(cloth_sim->node_state_index, NULL, NULL); + BLI_ghash_free(cloth_sim->node_state_index, nullptr, nullptr); if (cloth_sim->collider_list) { BKE_collider_cache_free(&cloth_sim->collider_list); } @@ -1339,7 +1331,7 @@ static EnumPropertyItem prop_cloth_filter_type[] = { 0, "Scale", "Scales the mesh as a soft body using the origin of the object as scale"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static EnumPropertyItem prop_cloth_filter_orientation_items[] = { @@ -1358,7 +1350,7 @@ static EnumPropertyItem prop_cloth_filter_orientation_items[] = { 0, "View", "Use the view axis to limit the force and set the gravity direction"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; typedef enum eClothFilterForceAxis { @@ -1371,7 +1363,7 @@ static EnumPropertyItem prop_cloth_filter_force_axis_items[] = { {CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"}, {CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"}, {CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static bool cloth_filter_is_deformation_filter(eSculptClothFilterType filter_type) @@ -1400,21 +1392,21 @@ static void cloth_filter_apply_forces_to_vertices(const int v_index, copy_v3_v3(final_force, force); SCULPT_filter_zero_disabled_axis_components(final_force, filter_cache); add_v3_v3(final_force, gravity); - cloth_brush_apply_force_to_vertex(NULL, filter_cache->cloth_sim, final_force, v_index); + cloth_brush_apply_force_to_vertex(nullptr, filter_cache->cloth_sim, final_force, v_index); } static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); Sculpt *sd = data->sd; SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; SculptClothSimulation *cloth_sim = ss->filter_cache->cloth_sim; - const eSculptClothFilterType filter_type = data->filter_type; + const eSculptClothFilterType filter_type = eSculptClothFilterType(data->filter_type); const bool is_deformation_filter = cloth_filter_is_deformation_filter(filter_type); float sculpt_gravity[3] = {0.0f}; @@ -1530,13 +1522,12 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, vertex)); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .filter_type = filter_type, - .filter_strength = filter_strength, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.filter_type = filter_type; + data.filter_strength = filter_strength; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); @@ -1565,10 +1556,10 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent Sculpt *sd = CTX_data_tool_settings(C)->sculpt; SculptSession *ss = ob->sculpt; - const eSculptClothFilterType filter_type = RNA_enum_get(op->ptr, "type"); + const eSculptClothFilterType filter_type = eSculptClothFilterType(RNA_enum_get(op->ptr, "type")); /* Update the active vertex */ - float mval_fl[2] = {UNPACK2(event->mval)}; + float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SculptCursorGeometryInfo sgi; SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); @@ -1583,7 +1574,7 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_filter_cache_init( C, ob, sd, SCULPT_UNDO_COORDS, event->mval, RNA_float_get(op->ptr, "area_normal_radius")); - ss->filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob); + ss->filter_cache->automasking = SCULPT_automasking_cache_init(sd, nullptr, ob); const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass"); const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping"); @@ -1622,14 +1613,15 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y; ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z; - SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation"); + SculptFilterOrientation orientation = SculptFilterOrientation( + RNA_enum_get(op->ptr, "orientation")); ss->filter_cache->orientation = orientation; WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -void SCULPT_OT_cloth_filter(struct wmOperatorType *ot) +void SCULPT_OT_cloth_filter(wmOperatorType *ot) { /* Identifiers. */ ot->name = "Filter Cloth"; diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.cc similarity index 91% rename from source/blender/editors/sculpt_paint/sculpt_detail.c rename to source/blender/editors/sculpt_paint/sculpt_detail.cc index 0e46fd50f3b..0bc52e83e58 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.c +++ b/source/blender/editors/sculpt_paint/sculpt_detail.cc @@ -32,26 +32,26 @@ #include "ED_screen.h" #include "ED_space_api.h" #include "ED_view3d.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" -#include -#include +#include +#include /* -------------------------------------------------------------------- */ /** \name Internal Utilities * \{ */ -typedef struct { +struct SculptDetailRaycastData { const float *ray_start; bool hit; float depth; float edge_length; - struct IsectRayPrecalc isect_precalc; -} SculptDetailRaycastData; + IsectRayPrecalc isect_precalc; +}; static bool sculpt_and_constant_or_manual_detail_poll(bContext *C) { @@ -85,7 +85,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op) int totnodes; PBVHNode **nodes; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnodes); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnodes); if (!totnodes) { return OPERATOR_CANCELLED; @@ -107,10 +107,10 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op) BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail); SCULPT_undo_push_begin(ob, op); - SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS); + SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_COORDS); while (BKE_pbvh_bmesh_update_topology( - ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, NULL, size, false, false)) { + ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false)) { for (int i = 0; i < totnodes; i++) { BKE_pbvh_node_mark_topology_update(nodes[i]); } @@ -155,21 +155,21 @@ typedef enum eSculptSampleDetailModeTypes { static EnumPropertyItem prop_sculpt_sample_detail_mode_types[] = { {SAMPLE_DETAIL_DYNTOPO, "DYNTOPO", 0, "Dyntopo", "Sample dyntopo detail"}, {SAMPLE_DETAIL_VOXEL, "VOXEL", 0, "Voxel", "Sample mesh voxel size"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2]) { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Object *ob = vc->obact; - Mesh *mesh = ob->data; + Mesh *mesh = static_cast(ob->data); SculptSession *ss = ob->sculpt; SculptCursorGeometryInfo sgi; SCULPT_vertex_random_access_ensure(ss); /* Update the active vertex. */ - const float mval_fl[2] = {UNPACK2(mval)}; + const float mval_fl[2] = {float(mval[0]), float(mval[1])}; SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); @@ -185,14 +185,14 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2]) } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); if (tot > 0) { - mesh->remesh_voxel_size = edge_length / (float)tot; + mesh->remesh_voxel_size = edge_length / float(tot); } } static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin) { if (BKE_pbvh_node_get_tmin(node) < *tmin) { - SculptDetailRaycastData *srd = data_v; + SculptDetailRaycastData *srd = static_cast(data_v); if (BKE_pbvh_bmesh_node_raycast_detail( node, srd->ray_start, &srd->isect_precalc, &srd->depth, &srd->edge_length)) { srd->hit = true; @@ -209,7 +209,7 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, const int mval[2 SCULPT_stroke_modifiers_check(C, ob, brush); - const float mval_fl[2] = {UNPACK2(mval)}; + const float mval_fl[2] = {float(mval[0]), float(mval[1])}; float ray_start[3], ray_end[3], ray_normal[3]; float depth = SCULPT_raycast_init(vc, mval_fl, ray_start, ray_end, ray_normal, false); @@ -233,8 +233,8 @@ static int sample_detail(bContext *C, const int event_xy[2], int mode) /* Find 3D view to pick from. */ bScreen *screen = CTX_wm_screen(C); ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, event_xy); - ARegion *region = (area) ? BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, event_xy) : NULL; - if (region == NULL) { + ARegion *region = (area) ? BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, event_xy) : nullptr; + if (region == nullptr) { return OPERATOR_CANCELLED; } @@ -249,7 +249,7 @@ static int sample_detail(bContext *C, const int event_xy[2], int mode) ED_view3d_viewcontext_init(C, &vc, depsgraph); Object *ob = vc.obact; - if (ob == NULL) { + if (ob == nullptr) { return OPERATOR_CANCELLED; } @@ -298,7 +298,7 @@ static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op) return sample_detail(C, ss_co, mode); } -static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e)) +static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { ED_workspace_status_text(C, TIP_("Click on the mesh to set the detail")); WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER); @@ -316,8 +316,8 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm RNA_int_set_array(op->ptr, "location", event->xy); WM_cursor_modal_restore(CTX_wm_window(C)); - ED_workspace_status_text(C, NULL); - WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL); + ED_workspace_status_text(C, nullptr); + WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, nullptr); return OPERATOR_FINISHED; } @@ -325,7 +325,7 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm case EVT_ESCKEY: case RIGHTMOUSE: { WM_cursor_modal_restore(CTX_wm_window(C)); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); return OPERATOR_CANCELLED; } @@ -352,7 +352,7 @@ void SCULPT_OT_sample_detail_size(wmOperatorType *ot) RNA_def_int_array(ot->srna, "location", 2, - NULL, + nullptr, 0, SHRT_MAX, "Location", @@ -409,12 +409,12 @@ static void sculpt_detail_size_set_radial_control(bContext *C) RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); } - WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, NULL); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, nullptr); WM_operator_properties_free(&props_ptr); } -static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_set_detail_size_exec(bContext *C, wmOperator * /*op*/) { sculpt_detail_size_set_radial_control(C); @@ -446,7 +446,7 @@ void SCULPT_OT_set_detail_size(wmOperatorType *ot) #define DETAIL_SIZE_DELTA_SPEED 0.08f #define DETAIL_SIZE_DELTA_ACCURATE_SPEED 0.004f -typedef struct DyntopoDetailSizeEditCustomData { +struct DyntopoDetailSizeEditCustomData { void *draw_handle; Object *active_object; @@ -465,7 +465,7 @@ typedef struct DyntopoDetailSizeEditCustomData { float preview_tri[3][3]; float gizmo_mat[4][4]; -} DyntopoDetailSizeEditCustomData; +}; static void dyntopo_detail_size_parallel_lines_draw(uint pos3d, DyntopoDetailSizeEditCustomData *cd, @@ -485,7 +485,7 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d, object_space_constant_detail *= 0.7f; const float total_len = len_v3v3(cd->preview_tri[0], cd->preview_tri[1]); - const int tot_lines = (int)(total_len / object_space_constant_detail) + 1; + const int tot_lines = int(total_len / object_space_constant_detail) + 1; const float tot_lines_fl = total_len / object_space_constant_detail; float spacing_disp[3]; sub_v3_v3v3(spacing_disp, end_co, start_co); @@ -495,14 +495,14 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d, rotate_v2_v2fl(line_disp, spacing_disp, DEG2RAD(angle)); mul_v3_fl(spacing_disp, total_len / tot_lines_fl); - immBegin(GPU_PRIM_LINES, (uint)tot_lines * 2); + immBegin(GPU_PRIM_LINES, uint(tot_lines) * 2); for (int i = 0; i < tot_lines; i++) { float line_length; if (flip) { - line_length = total_len * ((float)i / (float)tot_lines_fl); + line_length = total_len * (float(i) / float(tot_lines_fl)); } else { - line_length = total_len * (1.0f - ((float)i / (float)tot_lines_fl)); + line_length = total_len * (1.0f - (float(i) / float(tot_lines_fl))); } float line_start[3]; copy_v3_v3(line_start, start_co); @@ -515,11 +515,9 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d, immEnd(); } -static void dyntopo_detail_size_edit_draw(const bContext *UNUSED(C), - ARegion *UNUSED(ar), - void *arg) +static void dyntopo_detail_size_edit_draw(const bContext * /*C*/, ARegion * /*region*/, void *arg) { - DyntopoDetailSizeEditCustomData *cd = arg; + DyntopoDetailSizeEditCustomData *cd = static_cast(arg); GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); @@ -567,11 +565,12 @@ static void dyntopo_detail_size_edit_cancel(bContext *C, wmOperator *op) Object *active_object = CTX_data_active_object(C); SculptSession *ss = active_object->sculpt; ARegion *region = CTX_wm_region(C); - DyntopoDetailSizeEditCustomData *cd = op->customdata; + DyntopoDetailSizeEditCustomData *cd = static_cast( + op->customdata); ED_region_draw_cb_exit(region->type, cd->draw_handle); ss->draw_faded_cursor = false; MEM_freeN(op->customdata); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); } static void dyntopo_detail_size_sample_from_surface(Object *ob, @@ -602,7 +601,7 @@ static void dyntopo_detail_size_sample_from_surface(Object *ob, static void dyntopo_detail_size_update_from_mouse_delta(DyntopoDetailSizeEditCustomData *cd, const wmEvent *event) { - const float mval[2] = {event->mval[0], event->mval[1]}; + const float mval[2] = {float(event->mval[0]), float(event->mval[1])}; float detail_size_delta; if (cd->accurate_mode) { @@ -633,7 +632,8 @@ static int dyntopo_detail_size_edit_modal(bContext *C, wmOperator *op, const wmE Object *active_object = CTX_data_active_object(C); SculptSession *ss = active_object->sculpt; ARegion *region = CTX_wm_region(C); - DyntopoDetailSizeEditCustomData *cd = op->customdata; + DyntopoDetailSizeEditCustomData *cd = static_cast( + op->customdata); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; /* Cancel modal operator */ @@ -653,7 +653,7 @@ static int dyntopo_detail_size_edit_modal(bContext *C, wmOperator *op, const wmE ss->draw_faded_cursor = false; MEM_freeN(op->customdata); ED_region_tag_redraw(region); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); return OPERATOR_FINISHED; } @@ -696,8 +696,7 @@ static int dyntopo_detail_size_edit_invoke(bContext *C, wmOperator *op, const wm Object *active_object = CTX_data_active_object(C); Brush *brush = BKE_paint_brush(&sd->paint); - DyntopoDetailSizeEditCustomData *cd = MEM_callocN(sizeof(DyntopoDetailSizeEditCustomData), - "Dyntopo Detail Size Edit OP Custom Data"); + DyntopoDetailSizeEditCustomData *cd = MEM_cnew(__func__); /* Initial operator Custom Data setup. */ cd->draw_handle = ED_region_draw_cb_activate( diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc b/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc index a77b73ebaae..570e2e1cab3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc @@ -28,13 +28,15 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" +#include "BLI_index_range.hh" + #include "DEG_depsgraph.h" #include "WM_api.h" #include "WM_types.h" #include "ED_undo.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "UI_interface.h" #include "UI_resources.h" @@ -42,6 +44,8 @@ #include "bmesh.h" #include "bmesh_tools.h" +using blender::IndexRange; + void SCULPT_dynamic_topology_triangulate(BMesh *bm) { if (bm->totloop != bm->totface * 3) { @@ -87,7 +91,7 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags & SCULPT_DYNTOPO_SMOOTH_SHADING) != 0; - /* Dynamic topology doesn't ensure selection state is valid, so remove T36280. */ + /* Dynamic topology doesn't ensure selection state is valid, so remove #36280. */ BKE_mesh_mselect_clear(me); /* Create triangles-only BMesh. */ @@ -184,7 +188,7 @@ static void SCULPT_dynamic_topology_disable_ex( /* Clear data. */ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; - /* Typically valid but with global-undo they can be nullptr, see: T36234. */ + /* Typically valid but with global-undo they can be nullptr, see: #36234. */ if (ss->bm) { BM_mesh_free(ss->bm); ss->bm = nullptr; @@ -281,8 +285,8 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW uiLayout *layout = UI_popup_menu_layout(pup); if (flag & (DYNTOPO_WARN_VDATA | DYNTOPO_WARN_EDATA | DYNTOPO_WARN_LDATA)) { - const char *msg_error = TIP_("Vertex Data Detected!"); - const char *msg = TIP_("Dyntopo will not preserve vertex colors, UVs, or other customdata"); + const char *msg_error = TIP_("Attribute Data Detected"); + const char *msg = TIP_("Dyntopo will not preserve colors, UVs, or other attributes"); uiItemL(layout, msg_error, ICON_INFO); uiItemL(layout, msg, ICON_NONE); uiItemS(layout); @@ -305,6 +309,39 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW return OPERATOR_INTERFACE; } +static bool dyntopo_supports_customdata_layers(const blender::Span layers, + int totelem) +{ + for (const CustomDataLayer &layer : layers) { + if (CD_TYPE_AS_MASK(layer.type) & CD_MASK_PROP_ALL) { + if (layer.name[0] == '\0') { + return false; + } + + if (STREQ(layer.name, ".sculpt_face_sets") && totelem > 0) { + int *fsets = static_cast(layer.data); + int fset = fsets[0]; + + /* Check if only one face set exists. */ + for (int i : IndexRange(totelem)) { + if (fsets[i] != fset) { + return false; + } + } + + return true; + } + + /* Some data is stored as generic attributes on #Mesh but in flags or field on #BMesh. */ + return BM_attribute_stored_in_bmesh_builtin(layer.name); + } + /* Some layers just encode #Mesh topology or are handled as special cases for dyntopo. */ + return ELEM(layer.type, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX); + } + + return true; +} + enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob) { Mesh *me = static_cast(ob->data); @@ -315,18 +352,17 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob) BLI_assert(ss->bm == nullptr); UNUSED_VARS_NDEBUG(ss); - for (int i = 0; i < CD_NUMTYPES; i++) { - if (!ELEM(i, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX)) { - if (CustomData_has_layer(&me->vdata, i)) { - flag |= DYNTOPO_WARN_VDATA; - } - if (CustomData_has_layer(&me->edata, i)) { - flag |= DYNTOPO_WARN_EDATA; - } - if (CustomData_has_layer(&me->ldata, i)) { - flag |= DYNTOPO_WARN_LDATA; - } - } + if (!dyntopo_supports_customdata_layers({me->vdata.layers, me->vdata.totlayer}, me->totvert)) { + flag |= DYNTOPO_WARN_VDATA; + } + if (!dyntopo_supports_customdata_layers({me->edata.layers, me->edata.totlayer}, me->totedge)) { + flag |= DYNTOPO_WARN_EDATA; + } + if (!dyntopo_supports_customdata_layers({me->pdata.layers, me->pdata.totlayer}, me->totpoly)) { + flag |= DYNTOPO_WARN_LDATA; + } + if (!dyntopo_supports_customdata_layers({me->ldata.layers, me->ldata.totlayer}, me->totloop)) { + flag |= DYNTOPO_WARN_LDATA; } { diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index 64b71ba26f1..e6a69501ac5 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -44,7 +44,7 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 90ce21cdcf9..51ecaa168f3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -46,7 +46,7 @@ #include "ED_sculpt.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" @@ -548,7 +548,6 @@ static void sculpt_face_sets_init_flood_fill(Object *ob, const FaceSetsFloodFill if (!ss->epmap) { BKE_mesh_edge_poly_map_create(&ss->epmap, &ss->epmap_mem, - edges.data(), edges.size(), polys.data(), polys.size(), diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.cc similarity index 92% rename from source/blender/editors/sculpt_paint/sculpt_filter_color.c rename to source/blender/editors/sculpt_paint/sculpt_filter_color.cc index 0c0194da4e2..3ca6449ad50 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.cc @@ -25,15 +25,15 @@ #include "WM_types.h" #include "ED_paint.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" -#include -#include +#include +#include -typedef enum eSculptColorFilterTypes { +enum eSculptColorFilterTypes { COLOR_FILTER_FILL, COLOR_FILTER_HUE, COLOR_FILTER_SATURATION, @@ -44,7 +44,7 @@ typedef enum eSculptColorFilterTypes { COLOR_FILTER_GREEN, COLOR_FILTER_BLUE, COLOR_FILTER_SMOOTH, -} eSculptColorFilterTypes; +}; static EnumPropertyItem prop_color_filter_types[] = { {COLOR_FILTER_FILL, "FILL", 0, "Fill", "Fill with a specific color"}, @@ -60,14 +60,14 @@ static EnumPropertyItem prop_color_filter_types[] = { {COLOR_FILTER_RED, "RED", 0, "Red", "Change red channel"}, {COLOR_FILTER_GREEN, "GREEN", 0, "Green", "Change green channel"}, {COLOR_FILTER_BLUE, "BLUE", 0, "Blue", "Change blue channel"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static void color_filter_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const int mode = data->filter_type; @@ -222,8 +222,8 @@ static void sculpt_color_presmooth_init(SculptSession *ss) int totvert = SCULPT_vertex_count_get(ss); if (!ss->filter_cache->pre_smoothed_color) { - ss->filter_cache->pre_smoothed_color = MEM_malloc_arrayN( - totvert, sizeof(float) * 4, "ss->filter_cache->pre_smoothed_color"); + ss->filter_cache->pre_smoothed_color = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[4]), __func__)); } for (int i = 0; i < totvert; i++) { @@ -248,7 +248,7 @@ static void sculpt_color_presmooth_init(SculptSession *ss) SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); if (total > 0) { - mul_v4_fl(avg, 1.0f / (float)total); + mul_v4_fl(avg, 1.0f / float(total)); interp_v4_v4v4(ss->filter_cache->pre_smoothed_color[i], ss->filter_cache->pre_smoothed_color[i], avg, @@ -288,14 +288,13 @@ static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent sculpt_color_presmooth_init(ss); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .filter_type = mode, - .filter_strength = filter_strength, - .filter_fill_color = fill_color, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.filter_type = mode; + data.filter_strength = filter_strength; + data.filter_fill_color = fill_color; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -319,14 +318,14 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent v3d->shading.color_type = V3D_SHADING_VERTEX_COLOR; } - const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, NULL); + const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, nullptr); if (use_automasking) { /* Increment stroke id for auto-masking system. */ SCULPT_stroke_id_next(ob); /* Update the active face set manually as the paint cursor is not enabled when using the Mesh * Filter Tool. */ - float mval_fl[2] = {UNPACK2(event->mval)}; + float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SculptCursorGeometryInfo sgi; SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); } @@ -352,14 +351,14 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent C, ob, sd, SCULPT_UNDO_COLOR, event->mval, RNA_float_get(op->ptr, "area_normal_radius")); FilterCache *filter_cache = ss->filter_cache; filter_cache->active_face_set = SCULPT_FACE_SET_NONE; - filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob); + filter_cache->automasking = SCULPT_automasking_cache_init(sd, nullptr, ob); ED_paint_tool_update_sticky_shading_color(C, ob); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -void SCULPT_OT_color_filter(struct wmOperatorType *ot) +void SCULPT_OT_color_filter(wmOperatorType *ot) { /* identifiers */ ot->name = "Filter Color"; @@ -379,6 +378,6 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot) RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter Type", ""); PropertyRNA *prop = RNA_def_float_color( - ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f); + ot->srna, "fill_color", 3, nullptr, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f); RNA_def_property_subtype(prop, PROP_COLOR_GAMMA); } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc similarity index 90% rename from source/blender/editors/sculpt_paint/sculpt_filter_mask.c rename to source/blender/editors/sculpt_paint/sculpt_filter_mask.cc index 8e199a72858..c806ebdfd70 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc @@ -23,24 +23,24 @@ #include "WM_api.h" #include "WM_types.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" #include "bmesh.h" -#include -#include +#include +#include -typedef enum eSculptMaskFilterTypes { +enum eSculptMaskFilterTypes { MASK_FILTER_SMOOTH = 0, MASK_FILTER_SHARPEN = 1, MASK_FILTER_GROW = 2, MASK_FILTER_SHRINK = 3, MASK_FILTER_CONTRAST_INCREASE = 5, MASK_FILTER_CONTRAST_DECREASE = 6, -} eSculptMaskFilterTypes; +}; static EnumPropertyItem prop_mask_filter_types[] = { {MASK_FILTER_SMOOTH, "SMOOTH", 0, "Smooth Mask", "Smooth mask"}, @@ -57,14 +57,14 @@ static EnumPropertyItem prop_mask_filter_types[] = { 0, "Decrease Contrast", "Decrease the contrast of the paint mask"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static void mask_filter_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; bool update = false; @@ -182,14 +182,14 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) int num_verts = SCULPT_vertex_count_get(ss); - BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); SCULPT_undo_push_begin(ob, op); for (int i = 0; i < totnode; i++) { SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); } - float *prev_mask = NULL; + float *prev_mask = nullptr; int iterations = RNA_int_get(op->ptr, "iterations"); /* Auto iteration count calculates the number of iteration based on the vertices of the mesh to @@ -197,25 +197,24 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) * One iteration per 50000 vertices in the mesh should be fine in most cases. * Maybe we want this to be configurable. */ if (RNA_boolean_get(op->ptr, "auto_iteration_count")) { - iterations = (int)(num_verts / 50000.0f) + 1; + iterations = int(num_verts / 50000.0f) + 1; } for (int i = 0; i < iterations; i++) { if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) { - prev_mask = MEM_mallocN(num_verts * sizeof(float), "prevmask"); + prev_mask = static_cast(MEM_mallocN(num_verts * sizeof(float), __func__)); for (int j = 0; j < num_verts; j++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, j); prev_mask[j] = SCULPT_vertex_mask_get(ss, vertex); } } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .filter_type = filter_type, - .prev_mask = prev_mask, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = nodes; + data.filter_type = filter_type; + data.prev_mask = prev_mask; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -238,12 +237,11 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) void SCULPT_mask_filter_smooth_apply( Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations) { - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .filter_type = MASK_FILTER_SMOOTH, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = nodes; + data.filter_type = MASK_FILTER_SMOOTH; for (int i = 0; i < smooth_iterations; i++) { TaskParallelSettings settings; @@ -252,7 +250,7 @@ void SCULPT_mask_filter_smooth_apply( } } -void SCULPT_OT_mask_filter(struct wmOperatorType *ot) +void SCULPT_OT_mask_filter(wmOperatorType *ot) { /* Identifiers. */ ot->name = "Mask Filter"; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc similarity index 89% rename from source/blender/editors/sculpt_paint/sculpt_filter_mesh.c rename to source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc index 4367189c997..82f89c7f8f9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc @@ -26,7 +26,7 @@ #include "ED_view3d.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" @@ -35,10 +35,10 @@ #include "bmesh.h" -#include -#include +#include +#include -void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache) +void SCULPT_filter_to_orientation_space(float r_v[3], FilterCache *filter_cache) { switch (filter_cache->orientation) { case SCULPT_FILTER_ORIENTATION_LOCAL: @@ -54,7 +54,7 @@ void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter } } -void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache) +void SCULPT_filter_to_object_space(float r_v[3], FilterCache *filter_cache) { switch (filter_cache->orientation) { case SCULPT_FILTER_ORIENTATION_LOCAL: @@ -70,7 +70,7 @@ void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cach } } -void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCache *filter_cache) +void SCULPT_filter_zero_disabled_axis_components(float r_v[3], FilterCache *filter_cache) { SCULPT_filter_to_orientation_space(r_v, filter_cache); for (int axis = 0; axis < 3; axis++) { @@ -83,12 +83,12 @@ void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCach static void filter_cache_init_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); PBVHNode *node = data->nodes[i]; - SCULPT_undo_push_node(data->ob, node, data->filter_undo_type); + SCULPT_undo_push_node(data->ob, node, SculptUndoType(data->filter_undo_type)); } void SCULPT_filter_cache_init(bContext *C, @@ -101,7 +101,7 @@ void SCULPT_filter_cache_init(bContext *C, SculptSession *ss = ob->sculpt; PBVH *pbvh = ob->sculpt->pbvh; - ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache"); + ss->filter_cache = MEM_cnew(__func__); ss->filter_cache->random_seed = rand(); @@ -110,13 +110,12 @@ void SCULPT_filter_cache_init(bContext *C, } const float center[3] = {0.0f}; - SculptSearchSphereData search_data = { - .original = true, - .center = center, - .radius_squared = FLT_MAX, - .ignore_fully_ineffective = true, + SculptSearchSphereData search_data{}; + search_data.original = true; + search_data.center = center; + search_data.radius_squared = FLT_MAX; + search_data.ignore_fully_ineffective = true; - }; BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data, @@ -130,15 +129,14 @@ void SCULPT_filter_cache_init(bContext *C, /* `mesh->runtime.subdiv_ccg` is not available. Updating of the normals is done during drawing. * Filters can't use normals in multi-resolution. */ if (BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS) { - BKE_pbvh_update_normals(ss->pbvh, NULL); + BKE_pbvh_update_normals(ss->pbvh, nullptr); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .filter_undo_type = undo_type, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.filter_undo_type = undo_type; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); @@ -161,7 +159,7 @@ void SCULPT_filter_cache_init(bContext *C, UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; float co[3]; - float mval_fl[2] = {(float)mval[0], (float)mval[1]}; + float mval_fl[2] = {float(mval[0]), float(mval[1])}; if (SCULPT_stroke_get_location(C, co, mval_fl, false)) { PBVHNode **nodes; @@ -174,22 +172,21 @@ void SCULPT_filter_cache_init(bContext *C, if (brush) { if (BKE_brush_use_locked_size(scene, brush)) { radius = paint_calc_object_space_radius( - &vc, co, (float)BKE_brush_size_get(scene, brush) * area_normal_radius); + &vc, co, float(BKE_brush_size_get(scene, brush) * area_normal_radius)); } else { radius = BKE_brush_unprojected_radius_get(scene, brush) * area_normal_radius; } } else { - radius = paint_calc_object_space_radius(&vc, co, (float)ups->size * area_normal_radius); + radius = paint_calc_object_space_radius(&vc, co, float(ups->size) * area_normal_radius); } - SculptSearchSphereData search_data2 = { - .original = true, - .center = co, - .radius_squared = radius * radius, - .ignore_fully_ineffective = true, - }; + SculptSearchSphereData search_data2{}; + search_data2.original = true; + search_data2.center = co; + search_data2.radius_squared = radius * radius; + search_data2.ignore_fully_ineffective = true; BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2, &nodes, &totnode); @@ -295,7 +292,7 @@ static EnumPropertyItem prop_mesh_filter_types[] = { 0, "Erase Displacement", "Deletes the displacement of the Multires Modifier"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; typedef enum eMeshFilterDeformAxis { @@ -308,7 +305,7 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = { {MESH_FILTER_DEFORM_X, "X", 0, "X", "Deform in the X axis"}, {MESH_FILTER_DEFORM_Y, "Y", 0, "Y", "Deform in the Y axis"}, {MESH_FILTER_DEFORM_Z, "Z", 0, "Z", "Deform in the Z axis"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static EnumPropertyItem prop_mesh_filter_orientation_items[] = { @@ -327,7 +324,7 @@ static EnumPropertyItem prop_mesh_filter_orientation_items[] = { 0, "View", "Use the view axis to limit the displacement"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type) @@ -343,13 +340,13 @@ static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type) static void mesh_filter_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; - const eSculptMeshFilterType filter_type = data->filter_type; + const eSculptMeshFilterType filter_type = eSculptMeshFilterType(data->filter_type); SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i], SCULPT_UNDO_COORDS); @@ -442,7 +439,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, const uint *hash_co = (const uint *)orig_co; const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^ BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed); - mul_v3_fl(normal, hash * (1.0f / (float)0xFFFFFFFF) - 0.5f); + mul_v3_fl(normal, hash * (1.0f / float(0xFFFFFFFF)) - 0.5f); mul_v3_v3fl(disp, normal, fade); break; } @@ -546,8 +543,8 @@ static void mesh_filter_enhance_details_init_directions(SculptSession *ss) const int totvert = SCULPT_vertex_count_get(ss); FilterCache *filter_cache = ss->filter_cache; - filter_cache->detail_directions = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "detail directions"); + filter_cache->detail_directions = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__)); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -564,8 +561,8 @@ static void mesh_filter_surface_smooth_init(SculptSession *ss, const int totvert = SCULPT_vertex_count_get(ss); FilterCache *filter_cache = ss->filter_cache; - filter_cache->surface_smooth_laplacian_disp = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "surface smooth displacement"); + filter_cache->surface_smooth_laplacian_disp = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__)); filter_cache->surface_smooth_shape_preservation = shape_preservation; filter_cache->surface_smooth_current_vertex = current_vertex_displacement; } @@ -575,8 +572,8 @@ static void mesh_filter_init_limit_surface_co(SculptSession *ss) const int totvert = SCULPT_vertex_count_get(ss); FilterCache *filter_cache = ss->filter_cache; - filter_cache->limit_surface_co = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "limit surface co"); + filter_cache->limit_surface_co = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__)); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -595,9 +592,10 @@ static void mesh_filter_sharpen_init(SculptSession *ss, filter_cache->sharpen_smooth_ratio = smooth_ratio; filter_cache->sharpen_intensify_detail_strength = intensify_detail_strength; filter_cache->sharpen_curvature_smooth_iterations = curvature_smooth_iterations; - filter_cache->sharpen_factor = MEM_malloc_arrayN(totvert, sizeof(float), "sharpen factor"); - filter_cache->detail_directions = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "sharpen detail direction"); + filter_cache->sharpen_factor = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float), __func__)); + filter_cache->detail_directions = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__)); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -648,10 +646,11 @@ static void mesh_filter_sharpen_init(SculptSession *ss, } } -static void mesh_filter_surface_smooth_displace_task_cb( - void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) +static void mesh_filter_surface_smooth_displace_task_cb(void *__restrict userdata, + const int i, + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; PBVHVertexIter vd; @@ -688,7 +687,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent * Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type"); + eSculptMeshFilterType filter_type = eSculptMeshFilterType(RNA_enum_get(op->ptr, "type")); float filter_strength = RNA_float_get(op->ptr, "strength"); if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { @@ -710,13 +709,12 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent * bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type); BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .filter_type = filter_type, - .filter_strength = filter_strength, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.filter_type = filter_type; + data.filter_strength = filter_strength; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); @@ -753,9 +751,10 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent Sculpt *sd = CTX_data_tool_settings(C)->sculpt; SculptSession *ss = ob->sculpt; - const eMeshFilterDeformAxis deform_axis = RNA_enum_get(op->ptr, "deform_axis"); - const eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type"); - const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, NULL); + const eMeshFilterDeformAxis deform_axis = eMeshFilterDeformAxis( + RNA_enum_get(op->ptr, "deform_axis")); + const eSculptMeshFilterType filter_type = eSculptMeshFilterType(RNA_enum_get(op->ptr, "type")); + const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, nullptr); const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type) || use_automasking; if (deform_axis == 0) { @@ -769,7 +768,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent /* Update the active face set manually as the paint cursor is not enabled when using the Mesh * Filter Tool. */ - float mval_fl[2] = {UNPACK2(event->mval)}; + float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SculptCursorGeometryInfo sgi; SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); } @@ -787,7 +786,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent FilterCache *filter_cache = ss->filter_cache; filter_cache->active_face_set = SCULPT_FACE_SET_NONE; - filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob); + filter_cache->automasking = SCULPT_automasking_cache_init(sd, nullptr, ob); switch (filter_type) { case MESH_FILTER_SURFACE_SMOOTH: { @@ -823,14 +822,15 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y; ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z; - SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation"); + SculptFilterOrientation orientation = SculptFilterOrientation( + RNA_enum_get(op->ptr, "orientation")); ss->filter_cache->orientation = orientation; WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -void SCULPT_mesh_filter_properties(struct wmOperatorType *ot) +void SCULPT_mesh_filter_properties(wmOperatorType *ot) { RNA_def_float( ot->srna, @@ -846,7 +846,7 @@ void SCULPT_mesh_filter_properties(struct wmOperatorType *ot) ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f); } -void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) +void SCULPT_OT_mesh_filter(wmOperatorType *ot) { /* Identifiers. */ ot->name = "Filter Mesh"; diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc index 3c72f59477c..84232a295dd 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc @@ -28,7 +28,7 @@ #include "BKE_pbvh.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "bmesh.h" @@ -95,14 +95,8 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag"); if (!ss->epmap) { - BKE_mesh_edge_poly_map_create(&ss->epmap, - &ss->epmap_mem, - edges, - mesh->totedge, - polys, - mesh->totpoly, - loops, - mesh->totloop); + BKE_mesh_edge_poly_map_create( + &ss->epmap, &ss->epmap_mem, mesh->totedge, polys, mesh->totpoly, loops, mesh->totloop); } if (!ss->vemap) { BKE_mesh_vert_edge_map_create(&ss->vemap, &ss->vemap_mem, edges, mesh->totvert, mesh->totedge); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.hh similarity index 72% rename from source/blender/editors/sculpt_paint/sculpt_intern.h rename to source/blender/editors/sculpt_paint/sculpt_intern.hh index 154e9a7decc..37e7a522ccf 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -24,19 +24,20 @@ #include "ED_view3d.h" -#ifdef __cplusplus -extern "C" { -#endif - struct AutomaskingCache; struct AutomaskingNodeData; +struct Dial; +struct DistRayAABB_Precalc; struct Image; struct ImageUser; struct KeyBlock; struct Object; +struct SculptProjectVector; struct SculptUndoNode; struct bContext; struct PaintModeSettings; +struct WeightPaintInfo; +struct WPaintData; struct wmKeyConfig; struct wmOperator; struct wmOperatorType; @@ -47,23 +48,23 @@ struct wmOperatorType; /** \name Sculpt Types * \{ */ -typedef enum SculptUpdateType { +enum SculptUpdateType { SCULPT_UPDATE_COORDS = 1 << 0, SCULPT_UPDATE_MASK = 1 << 1, SCULPT_UPDATE_VISIBILITY = 1 << 2, SCULPT_UPDATE_COLOR = 1 << 3, SCULPT_UPDATE_IMAGE = 1 << 4, -} SculptUpdateType; +}; -typedef struct SculptCursorGeometryInfo { +struct SculptCursorGeometryInfo { float location[3]; float normal[3]; float active_vertex_co[3]; -} SculptCursorGeometryInfo; +}; #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256 -typedef struct SculptVertexNeighborIter { +struct SculptVertexNeighborIter { /* Storage */ PBVHVertRef *neighbors; int *neighbor_indices; @@ -81,13 +82,13 @@ typedef struct SculptVertexNeighborIter { int index; PBVHVertRef vertex; bool is_duplicate; -} SculptVertexNeighborIter; +}; /* Sculpt Original Data */ -typedef struct { +struct SculptOrigVertData { struct BMLog *bm_log; - struct SculptUndoNode *unode; + SculptUndoNode *unode; float (*coords)[3]; float (*normals)[3]; const float *vmasks; @@ -98,29 +99,29 @@ typedef struct { const float *no; float mask; const float *col; -} SculptOrigVertData; +}; -typedef struct SculptOrigFaceData { - struct SculptUndoNode *unode; +struct SculptOrigFaceData { + SculptUndoNode *unode; struct BMLog *bm_log; const int *face_sets; int face_set; -} SculptOrigFaceData; +}; /* Flood Fill. */ -typedef struct { +struct SculptFloodFill { GSQueue *queue; BLI_bitmap *visited_verts; -} SculptFloodFill; +}; -typedef enum eBoundaryAutomaskMode { +enum eBoundaryAutomaskMode { AUTOMASK_INIT_BOUNDARY_EDGES = 1, AUTOMASK_INIT_BOUNDARY_FACE_SETS = 2, -} eBoundaryAutomaskMode; +}; /* Undo */ -typedef enum { +enum SculptUndoType { SCULPT_UNDO_COORDS, SCULPT_UNDO_HIDDEN, SCULPT_UNDO_MASK, @@ -130,11 +131,11 @@ typedef enum { SCULPT_UNDO_GEOMETRY, SCULPT_UNDO_FACE_SETS, SCULPT_UNDO_COLOR, -} SculptUndoType; +}; /* Storage of geometry for the undo node. * Is used as a storage for either original or modified geometry. */ -typedef struct SculptUndoNodeGeometry { +struct SculptUndoNodeGeometry { /* Is used for sanity check, helping with ensuring that two and only two * geometry pushes happened in the undo stack. */ bool is_initialized; @@ -147,10 +148,10 @@ typedef struct SculptUndoNodeGeometry { int totedge; int totloop; int totpoly; -} SculptUndoNodeGeometry; +}; -typedef struct SculptUndoNode { - struct SculptUndoNode *next, *prev; +struct SculptUndoNode { + SculptUndoNode *next, *prev; SculptUndoType type; @@ -184,7 +185,7 @@ typedef struct SculptUndoNode { BLI_bitmap **grid_hidden; /* bmesh */ - struct BMLogEntry *bm_entry; + BMLogEntry *bm_entry; bool applied; /* shape keys */ @@ -214,7 +215,7 @@ typedef struct SculptUndoNode { int faces_num; size_t undo_size; -} SculptUndoNode; +}; /* Factor of brush to have rake point following behind * (could be configurable but this is reasonable default). */ @@ -230,19 +231,19 @@ struct SculptRakeData { * normally we would split it up, but it might be better to see if we can't eliminate it * altogether after moving to C++ (where we'll be able to use lambdas). */ -typedef struct SculptThreadedTaskData { - struct bContext *C; - struct Sculpt *sd; - struct Object *ob; - const struct Brush *brush; - struct PBVHNode **nodes; +struct SculptThreadedTaskData { + bContext *C; + Sculpt *sd; + Object *ob; + const Brush *brush; + PBVHNode **nodes; int totnode; - struct VPaint *vp; - struct WPaintData *wpd; - struct WeightPaintInfo *wpi; + VPaint *vp; + WPaintData *wpd; + WeightPaintInfo *wpi; unsigned int *lcol; - struct Mesh *me; + Mesh *me; /* For passing generic params. */ void *custom_data; @@ -257,7 +258,7 @@ typedef struct SculptThreadedTaskData { bool smooth_mask; bool has_bm_orco; - struct SculptProjectVector *spvc; + SculptProjectVector *spvc; float *offset; float *grab_delta; float *cono; @@ -345,10 +346,10 @@ typedef struct SculptThreadedTaskData { ThreadMutex mutex; int iteration; -} SculptThreadedTaskData; +}; /*************** Brush testing declarations ****************/ -typedef struct SculptBrushTest { +struct SculptBrushTest { float radius_squared; float radius; float location[3]; @@ -365,48 +366,48 @@ typedef struct SculptBrushTest { float plane_tool[4]; /* View3d clipping - only set rv3d for clipping */ - struct RegionView3D *clip_rv3d; -} SculptBrushTest; + RegionView3D *clip_rv3d; +}; -typedef bool (*SculptBrushTestFn)(SculptBrushTest *test, const float co[3]); +using SculptBrushTestFn = bool (*)(SculptBrushTest *test, const float co[3]); -typedef struct { - struct Sculpt *sd; - struct SculptSession *ss; +struct SculptSearchSphereData { + Sculpt *sd; + SculptSession *ss; float radius_squared; const float *center; bool original; /* This ignores fully masked and fully hidden nodes. */ bool ignore_fully_ineffective; -} SculptSearchSphereData; +}; -typedef struct { - struct Sculpt *sd; - struct SculptSession *ss; +struct SculptSearchCircleData { + Sculpt *sd; + SculptSession *ss; float radius_squared; bool original; bool ignore_fully_ineffective; - struct DistRayAABB_Precalc *dist_ray_to_aabb_precalc; -} SculptSearchCircleData; + DistRayAABB_Precalc *dist_ray_to_aabb_precalc; +}; /* Sculpt Filters */ -typedef enum SculptFilterOrientation { +enum SculptFilterOrientation { SCULPT_FILTER_ORIENTATION_LOCAL = 0, SCULPT_FILTER_ORIENTATION_WORLD = 1, SCULPT_FILTER_ORIENTATION_VIEW = 2, -} SculptFilterOrientation; +}; /* Defines how transform tools are going to apply its displacement. */ -typedef enum SculptTransformDisplacementMode { +enum SculptTransformDisplacementMode { /* Displaces the elements from their original coordinates. */ SCULPT_TRANSFORM_DISPLACEMENT_ORIGINAL = 0, /* Displaces the elements incrementally from their previous position. */ SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL = 1, -} SculptTransformDisplacementMode; +}; #define SCULPT_CLAY_STABILIZER_LEN 10 -typedef struct AutomaskingSettings { +struct AutomaskingSettings { /* Flags from eAutomasking_flag. */ int flags; int initial_face_set; @@ -414,22 +415,22 @@ typedef struct AutomaskingSettings { float cavity_factor; int cavity_blur_steps; - struct CurveMapping *cavity_curve; + CurveMapping *cavity_curve; float start_normal_limit, start_normal_falloff; float view_normal_limit, view_normal_falloff; bool topology_use_brush_limit; -} AutomaskingSettings; +}; -typedef struct AutomaskingCache { +struct AutomaskingCache { AutomaskingSettings settings; bool can_reuse_mask; uchar current_stroke_id; -} AutomaskingCache; +}; -typedef struct FilterCache { +struct FilterCache { bool enabled_axis[3]; bool enabled_force_axis[3]; int random_seed; @@ -493,13 +494,13 @@ typedef struct FilterCache { float (*pre_smoothed_color)[4]; ViewContext vc; -} FilterCache; +}; /** * This structure contains all the temporary data * needed for individual brush strokes. */ -typedef struct StrokeCache { +struct StrokeCache { /* Invariants */ float initial_radius; float scale[3]; @@ -555,8 +556,8 @@ typedef struct StrokeCache { float projection_mat[4][4]; /* Clean this up! */ - struct ViewContext *vc; - const struct Brush *brush; + ViewContext *vc; + const Brush *brush; float special_rotation; float grab_delta[3], grab_delta_symmetry[3]; @@ -565,7 +566,7 @@ typedef struct StrokeCache { /* screen-space rotation defined by mouse motion */ float rake_rotation[4], rake_rotation_symmetry[4]; bool is_rake_rotation_valid; - struct SculptRakeData rake_data; + SculptRakeData rake_data; /* Face Sets */ int paint_face_set; @@ -608,7 +609,7 @@ typedef struct StrokeCache { } paint_brush; /* Pose brush */ - struct SculptPoseIKChain *pose_ik_chain; + SculptPoseIKChain *pose_ik_chain; /* Enhance Details. */ float (*detail_directions)[3]; @@ -621,14 +622,14 @@ typedef struct StrokeCache { int clay_pressure_stabilizer_index; /* Cloth brush */ - struct SculptClothSimulation *cloth_sim; + SculptClothSimulation *cloth_sim; float initial_location[3]; float true_initial_location[3]; float initial_normal[3]; float true_initial_normal[3]; /* Boundary brush */ - struct SculptBoundary *boundaries[PAINT_SYMM_AREAS]; + SculptBoundary *boundaries[PAINT_SYMM_AREAS]; /* Surface Smooth Brush */ /* Stores the displacement produced by the laplacian step of HC smooth. */ @@ -638,7 +639,7 @@ typedef struct StrokeCache { float *layer_displacement_factor; float vertex_rotation; /* amount to rotate the vertices when using rotate brush */ - struct Dial *dial; + Dial *dial; char saved_active_brush_name[MAX_ID_NAME]; char saved_mask_brush_tool; @@ -664,13 +665,13 @@ typedef struct StrokeCache { rcti current_r; /* current redraw rectangle */ int stroke_id; -} StrokeCache; +}; /* -------------------------------------------------------------------- */ /** \name Sculpt Expand * \{ */ -typedef enum eSculptExpandFalloffType { +enum eSculptExpandFalloffType { SCULPT_EXPAND_FALLOFF_GEODESIC, SCULPT_EXPAND_FALLOFF_TOPOLOGY, SCULPT_EXPAND_FALLOFF_TOPOLOGY_DIAGONALS, @@ -679,22 +680,22 @@ typedef enum eSculptExpandFalloffType { SCULPT_EXPAND_FALLOFF_BOUNDARY_TOPOLOGY, SCULPT_EXPAND_FALLOFF_BOUNDARY_FACE_SET, SCULPT_EXPAND_FALLOFF_ACTIVE_FACE_SET, -} eSculptExpandFalloffType; +}; -typedef enum eSculptExpandTargetType { +enum eSculptExpandTargetType { SCULPT_EXPAND_TARGET_MASK, SCULPT_EXPAND_TARGET_FACE_SETS, SCULPT_EXPAND_TARGET_COLORS, -} eSculptExpandTargetType; +}; -typedef enum eSculptExpandRecursionType { +enum eSculptExpandRecursionType { SCULPT_EXPAND_RECURSION_TOPOLOGY, SCULPT_EXPAND_RECURSION_GEODESICS, -} eSculptExpandRecursionType; +}; #define EXPAND_SYMM_AREAS 8 -typedef struct ExpandCache { +struct ExpandCache { /* Target data elements that the expand operation will affect. */ eSculptExpandTargetType target; @@ -758,7 +759,7 @@ typedef struct ExpandCache { /* Texture distortion data. */ Brush *brush; - struct Scene *scene; + Scene *scene; // struct MTex *mtex; /* Controls how much texture distortion will be applied to the current falloff */ @@ -823,7 +824,7 @@ typedef struct ExpandCache { bool check_islands; int normal_falloff_blur_steps; -} ExpandCache; +}; /** \} */ /** \} */ @@ -832,13 +833,13 @@ typedef struct ExpandCache { /** \name Sculpt Poll Functions * \{ */ -bool SCULPT_mode_poll(struct bContext *C); -bool SCULPT_mode_poll_view3d(struct bContext *C); +bool SCULPT_mode_poll(bContext *C); +bool SCULPT_mode_poll_view3d(bContext *C); /** * Checks for a brush, not just sculpt mode. */ -bool SCULPT_poll(struct bContext *C); -bool SCULPT_poll_view3d(struct bContext *C); +bool SCULPT_poll(bContext *C); +bool SCULPT_poll_view3d(bContext *C); /** * Returns true if sculpt session can handle color attributes @@ -850,7 +851,7 @@ bool SCULPT_poll_view3d(struct bContext *C); * Calling code must handle this itself; in most cases a call to * BKE_sculpt_color_layer_create_if_needed() is sufficient. */ -bool SCULPT_handles_colors_report(struct SculptSession *ss, struct ReportList *reports); +bool SCULPT_handles_colors_report(SculptSession *ss, ReportList *reports); /** \} */ @@ -866,7 +867,7 @@ void SCULPT_pbvh_clear(Object *ob); /** * Flush displacement from deformed PBVH to original layer. */ -void SCULPT_flush_stroke_deform(struct Sculpt *sd, Object *ob, bool is_proxy_used); +void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used); /** * Should be used after modifying the mask or Face Sets IDs. @@ -885,7 +886,7 @@ void SCULPT_tag_update_overlays(bContext *C); * (This allows us to ignore the GL depth buffer) * Returns 0 if the ray doesn't hit the mesh, non-zero otherwise. */ -bool SCULPT_stroke_get_location(struct bContext *C, +bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mouse[2], bool force_original); @@ -897,10 +898,10 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], bool use_sampled_normal); -void SCULPT_geometry_preview_lines_update(bContext *C, struct SculptSession *ss, float radius); +void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float radius); void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush); -float SCULPT_raycast_init(struct ViewContext *vc, +float SCULPT_raycast_init(ViewContext *vc, const float mval[2], float ray_start[3], float ray_end[3], @@ -908,13 +909,13 @@ float SCULPT_raycast_init(struct ViewContext *vc, bool original); /* Symmetry */ -char SCULPT_mesh_symmetry_xyz_get(Object *object); +ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(Object *object); /** * Returns true when the step belongs to the stroke that is directly performed by the brush and * not by one of the symmetry passes. */ -bool SCULPT_stroke_is_main_symmetry_pass(struct StrokeCache *cache); +bool SCULPT_stroke_is_main_symmetry_pass(StrokeCache *cache); /** * Return true only once per stroke on the first symmetry pass, regardless of the symmetry passes * enabled. @@ -922,11 +923,11 @@ bool SCULPT_stroke_is_main_symmetry_pass(struct StrokeCache *cache); * This should be used for functionality that needs to be computed once per stroke of a particular * tool (allocating memory, updating random seeds...). */ -bool SCULPT_stroke_is_first_brush_step(struct StrokeCache *cache); +bool SCULPT_stroke_is_first_brush_step(StrokeCache *cache); /** * Returns true on the first brush step of each symmetry pass. */ -bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(struct StrokeCache *cache); +bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache); /** \} */ @@ -935,15 +936,15 @@ bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(struct StrokeCache *cach * \{ */ /** Ensure random access; required for PBVH_BMESH */ -void SCULPT_vertex_random_access_ensure(struct SculptSession *ss); +void SCULPT_vertex_random_access_ensure(SculptSession *ss); -int SCULPT_vertex_count_get(struct SculptSession *ss); -const float *SCULPT_vertex_co_get(struct SculptSession *ss, PBVHVertRef vertex); +int SCULPT_vertex_count_get(SculptSession *ss); +const float *SCULPT_vertex_co_get(SculptSession *ss, PBVHVertRef vertex); /** Get the normal for a given sculpt vertex; do not modify the result */ void SCULPT_vertex_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]); -float SCULPT_vertex_mask_get(struct SculptSession *ss, PBVHVertRef vertex); +float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex); void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4]); void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4]); @@ -953,7 +954,7 @@ bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool origi bool SCULPT_has_colors(const SculptSession *ss); /** Returns true if the active color attribute is on loop (ATTR_DOMAIN_CORNER) domain. */ -bool SCULPT_has_loop_colors(const struct Object *ob); +bool SCULPT_has_loop_colors(const Object *ob); const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, PBVHVertRef vertex); void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]); @@ -977,7 +978,7 @@ float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, int deform_target, PBVHVertexIter *iter); -void SCULPT_vertex_neighbors_get(struct SculptSession *ss, +void SCULPT_vertex_neighbors_get(SculptSession *ss, PBVHVertRef vertex, bool include_duplicates, SculptVertexNeighborIter *iter); @@ -1020,10 +1021,10 @@ float (*SCULPT_mesh_deformed_positions_get(SculptSession *ss))[3]; #define FAKE_NEIGHBOR_NONE -1 -void SCULPT_fake_neighbors_ensure(struct Sculpt *sd, Object *ob, float max_dist); +void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, float max_dist); void SCULPT_fake_neighbors_enable(Object *ob); void SCULPT_fake_neighbors_disable(Object *ob); -void SCULPT_fake_neighbors_free(struct Object *ob); +void SCULPT_fake_neighbors_free(Object *ob); /* Vertex Info. */ void SCULPT_boundary_info_ensure(Object *object); @@ -1044,7 +1045,7 @@ bool SCULPT_vertex_any_face_visible_get(SculptSession *ss, PBVHVertRef vertex); void SCULPT_face_visibility_all_invert(SculptSession *ss); void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible); -void SCULPT_visibility_sync_all_from_faces(struct Object *ob); +void SCULPT_visibility_sync_all_from_faces(Object *ob); /** \} */ @@ -1088,9 +1089,7 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter * Initialize a #SculptOrigVertData for accessing original vertex data; * handles #BMesh, #Mesh, and multi-resolution. */ -void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, - Object *ob, - struct SculptUndoNode *unode); +void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, SculptUndoNode *unode); /** * Initialize a #SculptOrigFaceData for accessing original face data; * handles #BMesh, #Mesh, and multi-resolution. @@ -1107,9 +1106,7 @@ void SCULPT_orig_face_data_update(SculptOrigFaceData *orig_data, PBVHFaceIter *i * Initialize a #SculptOrigVertData for accessing original vertex data; * handles #BMesh, #Mesh, and multi-resolution. */ -void SCULPT_orig_face_data_unode_init(SculptOrigFaceData *data, - Object *ob, - struct SculptUndoNode *unode); +void SCULPT_orig_face_data_unode_init(SculptOrigFaceData *data, Object *ob, SculptUndoNode *unode); /** \} */ /* -------------------------------------------------------------------- */ @@ -1148,12 +1145,8 @@ BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush) return false; } -void SCULPT_calc_brush_plane(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode, - float r_area_no[3], - float r_area_co[3]); +void SCULPT_calc_brush_plane( + Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]); void SCULPT_calc_area_normal( Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3]); @@ -1166,16 +1159,11 @@ void SCULPT_calc_area_normal_and_center( void SCULPT_calc_area_center( Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3]); -PBVHVertRef SCULPT_nearest_vertex_get(struct Sculpt *sd, - struct Object *ob, - const float co[3], - float max_distance, - bool use_original); +PBVHVertRef SCULPT_nearest_vertex_get( + Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original); int SCULPT_plane_point_side(const float co[3], const float plane[4]); -int SCULPT_plane_trim(const struct StrokeCache *cache, - const struct Brush *brush, - const float val[3]); +int SCULPT_plane_trim(const StrokeCache *cache, const Brush *brush, const float val[3]); /** * Handles clipping against a mirror modifier and #SCULPT_LOCK_X/Y/Z axis flags. */ @@ -1205,7 +1193,7 @@ void SCULPT_flip_quat_by_symm_area(float quat[4], /** * Initialize a point-in-brush test */ -void SCULPT_brush_test_init(struct SculptSession *ss, SculptBrushTest *test); +void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test); bool SCULPT_brush_test_sphere(SculptBrushTest *test, const float co[3]); bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3]); @@ -1242,8 +1230,8 @@ const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss, /** * Return a multiplier for brush strength on a particular vertex. */ -float SCULPT_brush_strength_factor(struct SculptSession *ss, - const struct Brush *br, +float SCULPT_brush_strength_factor(SculptSession *ss, + const Brush *br, const float point[3], float len, const float vno[3], @@ -1251,14 +1239,12 @@ float SCULPT_brush_strength_factor(struct SculptSession *ss, float mask, const PBVHVertRef vertex, int thread_id, - struct AutomaskingNodeData *automask_data); + AutomaskingNodeData *automask_data); /** * Tilts a normal by the x and y tilt values using the view axis. */ -void SCULPT_tilt_apply_to_normal(float r_normal[3], - struct StrokeCache *cache, - float tilt_strength); +void SCULPT_tilt_apply_to_normal(float r_normal[3], StrokeCache *cache, float tilt_strength); /** * Get effective surface normal with pen tilt and tilt strength applied to it. @@ -1271,21 +1257,18 @@ void SCULPT_tilt_effective_normal_get(const SculptSession *ss, const Brush *brus /** \name Flood Fill * \{ */ -void SCULPT_floodfill_init(struct SculptSession *ss, SculptFloodFill *flood); -void SCULPT_floodfill_add_active(struct Sculpt *sd, - struct Object *ob, - struct SculptSession *ss, - SculptFloodFill *flood, - float radius); -void SCULPT_floodfill_add_initial_with_symmetry(struct Sculpt *sd, - struct Object *ob, - struct SculptSession *ss, +void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood); +void SCULPT_floodfill_add_active( + Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius); +void SCULPT_floodfill_add_initial_with_symmetry(Sculpt *sd, + Object *ob, + SculptSession *ss, SculptFloodFill *flood, PBVHVertRef vertex, float radius); void SCULPT_floodfill_add_initial(SculptFloodFill *flood, PBVHVertRef vertex); void SCULPT_floodfill_add_and_skip_initial(SculptFloodFill *flood, PBVHVertRef vertex); -void SCULPT_floodfill_execute(struct SculptSession *ss, +void SCULPT_floodfill_execute(SculptSession *ss, SculptFloodFill *flood, bool (*func)(SculptSession *ss, PBVHVertRef from_v, @@ -1310,13 +1293,13 @@ enum eDynTopoWarnFlag { ENUM_OPERATORS(eDynTopoWarnFlag, DYNTOPO_WARN_MODIFIER); /** Enable dynamic topology; mesh will be triangulated */ -void SCULPT_dynamic_topology_enable_ex(struct Main *bmain, - struct Depsgraph *depsgraph, +void SCULPT_dynamic_topology_enable_ex(Main *bmain, + Depsgraph *depsgraph, Scene *scene, Object *ob); -void SCULPT_dynamic_topology_disable(bContext *C, struct SculptUndoNode *unode); -void sculpt_dynamic_topology_disable_with_undo(struct Main *bmain, - struct Depsgraph *depsgraph, +void SCULPT_dynamic_topology_disable(bContext *C, SculptUndoNode *unode); +void sculpt_dynamic_topology_disable_with_undo(Main *bmain, + Depsgraph *depsgraph, Scene *scene, Object *ob); @@ -1330,7 +1313,7 @@ void sculpt_dynamic_topology_disable_with_undo(struct Main *bmain, */ bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *brush); -void SCULPT_dynamic_topology_triangulate(struct BMesh *bm); +void SCULPT_dynamic_topology_triangulate(BMesh *bm); enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob); @@ -1340,18 +1323,18 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob); /** \name Auto-masking. * \{ */ -typedef struct AutomaskingNodeData { +struct AutomaskingNodeData { PBVHNode *node; SculptOrigVertData orig_data; bool have_orig_data; -} AutomaskingNodeData; +}; /** Call before PBVH vertex iteration. * \param automask_data: pointer to an uninitialized AutomaskingNodeData struct. */ -void SCULPT_automasking_node_begin(struct Object *ob, +void SCULPT_automasking_node_begin(Object *ob, const SculptSession *ss, - struct AutomaskingCache *automasking, + AutomaskingCache *automasking, AutomaskingNodeData *automask_data, PBVHNode *node); @@ -1360,18 +1343,18 @@ void SCULPT_automasking_node_update(SculptSession *ss, AutomaskingNodeData *automask_data, PBVHVertexIter *vd); -float SCULPT_automasking_factor_get(struct AutomaskingCache *automasking, +float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, PBVHVertRef vertex, AutomaskingNodeData *automask_data); /* Returns the automasking cache depending on the active tool. Used for code that can run both for * brushes and filter. */ -struct AutomaskingCache *SCULPT_automasking_active_cache_get(SculptSession *ss); +AutomaskingCache *SCULPT_automasking_active_cache_get(SculptSession *ss); /* Brush can be null. */ -struct AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob); -void SCULPT_automasking_cache_free(struct AutomaskingCache *automasking); +AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob); +void SCULPT_automasking_cache_free(AutomaskingCache *automasking); bool SCULPT_is_automasking_mode_enabled(const Sculpt *sd, const Brush *br, eAutomasking_flag mode); bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, const Brush *br); @@ -1383,7 +1366,7 @@ float *SCULPT_boundary_automasking_init(Object *ob, bool SCULPT_automasking_needs_normal(const SculptSession *ss, const Sculpt *sculpt, const Brush *brush); -bool SCULPT_automasking_needs_original(const struct Sculpt *sd, const struct Brush *brush); +bool SCULPT_automasking_needs_original(const Sculpt *sd, const Brush *brush); int SCULPT_automasking_settings_hash(Object *ob, AutomaskingCache *automasking); /** \} */ @@ -1398,11 +1381,9 @@ int SCULPT_automasking_settings_hash(Object *ob, AutomaskingCache *automasking); * Geodesic distances will only work when used with PBVH_FACES, for other types of PBVH it will * fallback to euclidean distances to one of the initial vertices in the set. */ -float *SCULPT_geodesic_distances_create(struct Object *ob, - struct GSet *initial_verts, - float limit_radius); -float *SCULPT_geodesic_from_vertex_and_symm(struct Sculpt *sd, - struct Object *ob, +float *SCULPT_geodesic_distances_create(Object *ob, GSet *initial_verts, float limit_radius); +float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, + Object *ob, PBVHVertRef vertex, float limit_radius); float *SCULPT_geodesic_from_vertex(Object *ob, PBVHVertRef vertex, float limit_radius); @@ -1412,22 +1393,22 @@ float *SCULPT_geodesic_from_vertex(Object *ob, PBVHVertRef vertex, float limit_r /** \name Filter API * \{ */ -void SCULPT_filter_cache_init(struct bContext *C, +void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, int undo_type, const int mval[2], float area_normal_radius); void SCULPT_filter_cache_free(SculptSession *ss); -void SCULPT_mesh_filter_properties(struct wmOperatorType *ot); +void SCULPT_mesh_filter_properties(wmOperatorType *ot); void SCULPT_mask_filter_smooth_apply( Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, int smooth_iterations); /* Filter orientation utils. */ -void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache); -void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache); -void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCache *filter_cache); +void SCULPT_filter_to_orientation_space(float r_v[3], FilterCache *filter_cache); +void SCULPT_filter_to_object_space(float r_v[3], FilterCache *filter_cache); +void SCULPT_filter_zero_disabled_axis_components(float r_v[3], FilterCache *filter_cache); /** \} */ @@ -1436,42 +1417,35 @@ void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCach * \{ */ /* Main cloth brush function */ -void SCULPT_do_cloth_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); +void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim); +void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim); /* Public functions. */ -struct SculptClothSimulation *SCULPT_cloth_brush_simulation_create(struct Object *ob, - float cloth_mass, - float cloth_damping, - float cloth_softbody_strength, - bool use_collisions, - bool needs_deform_coords); -void SCULPT_cloth_brush_simulation_init(struct SculptSession *ss, - struct SculptClothSimulation *cloth_sim); +SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob, + float cloth_mass, + float cloth_damping, + float cloth_softbody_strength, + bool use_collisions, + bool needs_deform_coords); +void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim); -void SCULPT_cloth_sim_activate_nodes(struct SculptClothSimulation *cloth_sim, +void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode); -void SCULPT_cloth_brush_store_simulation_state(struct SculptSession *ss, - struct SculptClothSimulation *cloth_sim); +void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, + SculptClothSimulation *cloth_sim); -void SCULPT_cloth_brush_do_simulation_step(struct Sculpt *sd, - struct Object *ob, - struct SculptClothSimulation *cloth_sim, - struct PBVHNode **nodes, - int totnode); +void SCULPT_cloth_brush_do_simulation_step( + Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode); -void SCULPT_cloth_brush_ensure_nodes_constraints(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, +void SCULPT_cloth_brush_ensure_nodes_constraints(Sculpt *sd, + Object *ob, + PBVHNode **nodes, int totnode, - struct SculptClothSimulation *cloth_sim, + SculptClothSimulation *cloth_sim, float initial_location[3], float radius); @@ -1479,7 +1453,7 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(struct Sculpt *sd, * Cursor drawing function. */ void SCULPT_cloth_simulation_limits_draw(uint gpuattr, - const struct Brush *brush, + const Brush *brush, const float location[3], const float normal[3], float rds, @@ -1487,7 +1461,7 @@ void SCULPT_cloth_simulation_limits_draw(uint gpuattr, const float outline_col[3], float alpha); void SCULPT_cloth_plane_falloff_preview_draw(uint gpuattr, - struct SculptSession *ss, + SculptSession *ss, const float outline_col[3], float outline_alpha); @@ -1515,7 +1489,7 @@ BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) * For bmesh: Average surrounding verts based on an orthogonality measure. * Naturally converges to a quad-like structure. */ -void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], struct BMVert *v); +void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], BMVert *v); void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], PBVHVertRef vertex); float SCULPT_neighbor_mask_average(SculptSession *ss, PBVHVertRef vertex); @@ -1550,8 +1524,8 @@ void SCULPT_surface_smooth_displace_step(SculptSession *ss, void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); /* Slide/Relax */ -void SCULPT_relax_vertex(struct SculptSession *ss, - struct PBVHVertexIter *vd, +void SCULPT_relax_vertex(SculptSession *ss, + PBVHVertexIter *vd, float factor, bool filter_boundary_face_sets, float *r_final_pos); @@ -1561,7 +1535,7 @@ void SCULPT_relax_vertex(struct SculptSession *ss, /** * Expose 'calc_area_normal' externally (just for vertex paint). */ -bool SCULPT_pbvh_calc_area_normal(const struct Brush *brush, +bool SCULPT_pbvh_calc_area_normal(const Brush *brush, Object *ob, PBVHNode **nodes, int totnode, @@ -1591,15 +1565,15 @@ SculptUndoNode *SCULPT_undo_get_first_node(void); * redo panels to work; operators that do not support that may use * #SCULPT_undo_push_begin_ex instead if so desired. */ -void SCULPT_undo_push_begin(struct Object *ob, const struct wmOperator *op); +void SCULPT_undo_push_begin(Object *ob, const wmOperator *op); /** * NOTE: #SCULPT_undo_push_begin is preferred since `name` * must match operator name for redo panels to work. */ -void SCULPT_undo_push_begin_ex(struct Object *ob, const char *name); -void SCULPT_undo_push_end(struct Object *ob); -void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo); +void SCULPT_undo_push_begin_ex(Object *ob, const char *name); +void SCULPT_undo_push_end(Object *ob); +void SCULPT_undo_push_end_ex(Object *ob, const bool use_nested_undo); /** \} */ @@ -1608,15 +1582,12 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]); /** * Copy the PBVH bounding box into the object's bounding box. */ -void SCULPT_update_object_bounding_box(struct Object *ob); +void SCULPT_update_object_bounding_box(Object *ob); /** * Get a screen-space rectangle of the modified area. */ -bool SCULPT_get_redraw_rect(struct ARegion *region, - struct RegionView3D *rv3d, - Object *ob, - rcti *rect); +bool SCULPT_get_redraw_rect(ARegion *region, RegionView3D *rv3d, Object *ob, rcti *rect); /* Operators. */ @@ -1624,32 +1595,32 @@ bool SCULPT_get_redraw_rect(struct ARegion *region, /** \name Expand Operator * \{ */ -void SCULPT_OT_expand(struct wmOperatorType *ot); -void sculpt_expand_modal_keymap(struct wmKeyConfig *keyconf); +void SCULPT_OT_expand(wmOperatorType *ot); +void sculpt_expand_modal_keymap(wmKeyConfig *keyconf); /** \} */ /* -------------------------------------------------------------------- */ /** \name Gesture Operators * \{ */ -void SCULPT_OT_face_set_lasso_gesture(struct wmOperatorType *ot); -void SCULPT_OT_face_set_box_gesture(struct wmOperatorType *ot); +void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot); +void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot); -void SCULPT_OT_trim_lasso_gesture(struct wmOperatorType *ot); -void SCULPT_OT_trim_box_gesture(struct wmOperatorType *ot); +void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot); +void SCULPT_OT_trim_box_gesture(wmOperatorType *ot); -void SCULPT_OT_project_line_gesture(struct wmOperatorType *ot); +void SCULPT_OT_project_line_gesture(wmOperatorType *ot); /** \} */ /* -------------------------------------------------------------------- */ /** \name Face Set Operators * \{ */ -void SCULPT_OT_face_sets_randomize_colors(struct wmOperatorType *ot); -void SCULPT_OT_face_sets_change_visibility(struct wmOperatorType *ot); -void SCULPT_OT_face_sets_init(struct wmOperatorType *ot); -void SCULPT_OT_face_sets_create(struct wmOperatorType *ot); -void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot); +void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot); +void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot); +void SCULPT_OT_face_sets_init(wmOperatorType *ot); +void SCULPT_OT_face_sets_create(wmOperatorType *ot); +void SCULPT_OT_face_sets_edit(wmOperatorType *ot); /** \} */ @@ -1657,7 +1628,7 @@ void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot); /** \name Transform Operators * \{ */ -void SCULPT_OT_set_pivot_position(struct wmOperatorType *ot); +void SCULPT_OT_set_pivot_position(wmOperatorType *ot); /** \} */ /* -------------------------------------------------------------------- */ @@ -1666,15 +1637,15 @@ void SCULPT_OT_set_pivot_position(struct wmOperatorType *ot); /* Mesh Filter. */ -void SCULPT_OT_mesh_filter(struct wmOperatorType *ot); +void SCULPT_OT_mesh_filter(wmOperatorType *ot); /* Cloth Filter. */ -void SCULPT_OT_cloth_filter(struct wmOperatorType *ot); +void SCULPT_OT_cloth_filter(wmOperatorType *ot); /* Color Filter. */ -void SCULPT_OT_color_filter(struct wmOperatorType *ot); +void SCULPT_OT_color_filter(wmOperatorType *ot); /** \} */ @@ -1684,15 +1655,15 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot); /* Mask filter and Dirty Mask. */ -void SCULPT_OT_mask_filter(struct wmOperatorType *ot); +void SCULPT_OT_mask_filter(wmOperatorType *ot); /* Mask and Face Sets Expand. */ -void SCULPT_OT_mask_expand(struct wmOperatorType *ot); +void SCULPT_OT_mask_expand(wmOperatorType *ot); /* Mask Init. */ -void SCULPT_OT_mask_init(struct wmOperatorType *ot); +void SCULPT_OT_mask_init(wmOperatorType *ot); /** \} */ /* Detail size. */ @@ -1701,17 +1672,17 @@ void SCULPT_OT_mask_init(struct wmOperatorType *ot); /** \name Dyntopo/Retopology Operators * \{ */ -void SCULPT_OT_detail_flood_fill(struct wmOperatorType *ot); -void SCULPT_OT_sample_detail_size(struct wmOperatorType *ot); -void SCULPT_OT_set_detail_size(struct wmOperatorType *ot); -void SCULPT_OT_dyntopo_detail_size_edit(struct wmOperatorType *ot); +void SCULPT_OT_detail_flood_fill(wmOperatorType *ot); +void SCULPT_OT_sample_detail_size(wmOperatorType *ot); +void SCULPT_OT_set_detail_size(wmOperatorType *ot); +void SCULPT_OT_dyntopo_detail_size_edit(wmOperatorType *ot); /** \} */ /* Dyntopo. */ -void SCULPT_OT_dynamic_topology_toggle(struct wmOperatorType *ot); +void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot); -/* sculpt_brush_types.c */ +/* sculpt_brush_types.cc */ /* -------------------------------------------------------------------- */ /** \name Brushes @@ -1722,10 +1693,7 @@ void SCULPT_OT_dynamic_topology_toggle(struct wmOperatorType *ot); /** * Main Brush Function. */ -void SCULPT_do_pose_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); +void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); /** * Calculate the pose origin and (Optionally the pose factor) * that is used when using the pose brush. @@ -1733,25 +1701,22 @@ void SCULPT_do_pose_brush(struct Sculpt *sd, * \param r_pose_origin: Must be a valid pointer. * \param r_pose_factor: Optional, when set to NULL it won't be calculated. */ -void SCULPT_pose_calc_pose_data(struct Sculpt *sd, - struct Object *ob, - struct SculptSession *ss, +void SCULPT_pose_calc_pose_data(Sculpt *sd, + Object *ob, + SculptSession *ss, float initial_location[3], float radius, float pose_offset, float *r_pose_origin, float *r_pose_factor); -void SCULPT_pose_brush_init(struct Sculpt *sd, - struct Object *ob, - struct SculptSession *ss, - struct Brush *br); -struct SculptPoseIKChain *SCULPT_pose_ik_chain_init(struct Sculpt *sd, - struct Object *ob, - struct SculptSession *ss, - struct Brush *br, - const float initial_location[3], - float radius); -void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain); +void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br); +SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd, + Object *ob, + SculptSession *ss, + Brush *br, + const float initial_location[3], + float radius); +void SCULPT_pose_ik_chain_free(SculptPoseIKChain *ik_chain); /* Boundary Brush. */ @@ -1759,22 +1724,19 @@ void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain); * Main function to get #SculptBoundary data both for brush deformation and viewport preview. * Can return NULL if there is no boundary from the given vertex using the given radius. */ -struct SculptBoundary *SCULPT_boundary_data_init(Object *object, - Brush *brush, - PBVHVertRef initial_vertex, - float radius); -void SCULPT_boundary_data_free(struct SculptBoundary *boundary); +SculptBoundary *SCULPT_boundary_data_init(Object *object, + Brush *brush, + PBVHVertRef initial_vertex, + float radius); +void SCULPT_boundary_data_free(SculptBoundary *boundary); /* Main Brush Function. */ -void SCULPT_do_boundary_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); +void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); void SCULPT_boundary_edges_preview_draw(uint gpuattr, - struct SculptSession *ss, + SculptSession *ss, const float outline_col[3], float outline_alpha); -void SCULPT_boundary_pivot_line_preview_draw(uint gpuattr, struct SculptSession *ss); +void SCULPT_boundary_pivot_line_preview_draw(uint gpuattr, SculptSession *ss); /* Multi-plane Scrape Brush. */ /* Main Brush Function. */ @@ -1788,7 +1750,7 @@ void SCULPT_multiplane_scrape_preview_draw(uint gpuattr, void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); /* Paint Brush. */ -void SCULPT_do_paint_brush(struct PaintModeSettings *paint_mode_settings, +void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, PBVHNode **nodes, @@ -1803,128 +1765,59 @@ void SCULPT_do_paint_brush(struct PaintModeSettings *paint_mode_settings, * image and image user. Returns false when the image isn't found. In the later case the r_image * and r_image_user are set to NULL. */ -bool SCULPT_paint_image_canvas_get(struct PaintModeSettings *paint_mode_settings, - struct Object *ob, - struct Image **r_image, - struct ImageUser **r_image_user) ATTR_NONNULL(); -void SCULPT_do_paint_brush_image(struct PaintModeSettings *paint_mode_settings, +bool SCULPT_paint_image_canvas_get(PaintModeSettings *paint_mode_settings, + Object *ob, + Image **r_image, + ImageUser **r_image_user) ATTR_NONNULL(); +void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, PBVHNode **texnodes, int texnode_num) ATTR_NONNULL(); -bool SCULPT_use_image_paint_brush(struct PaintModeSettings *settings, Object *ob) ATTR_NONNULL(); +bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob) ATTR_NONNULL(); /* Smear Brush. */ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -float SCULPT_clay_thumb_get_stabilized_pressure(struct StrokeCache *cache); +float SCULPT_clay_thumb_get_stabilized_pressure(StrokeCache *cache); -void SCULPT_do_draw_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); +void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_fill_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_scrape_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_clay_thumb_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_flatten_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_clay_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_clay_strips_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_snake_hook_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_thumb_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_rotate_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_layer_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_inflate_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_nudge_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_crease_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_pinch_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_grab_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_elastic_deform_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_draw_sharp_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_slide_relax_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); +void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_displacement_smear_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_displacement_eraser_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_mask_brush_draw(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); -void SCULPT_do_mask_brush(struct Sculpt *sd, - struct Object *ob, - struct PBVHNode **nodes, - int totnode); +void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); /** \} */ void SCULPT_bmesh_topology_rake( - struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, int totnode, float bstrength); + Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength); -/* end sculpt_brush_types.c */ +/* end sculpt_brush_types.cc */ -/* sculpt_ops.c */ +/* sculpt_ops.cc */ -void SCULPT_OT_brush_stroke(struct wmOperatorType *ot); +void SCULPT_OT_brush_stroke(wmOperatorType *ot); -/* end sculpt_ops.c */ +/* end sculpt_ops.cc */ BLI_INLINE bool SCULPT_tool_is_paint(int tool) { @@ -1941,11 +1834,11 @@ BLI_INLINE bool SCULPT_tool_is_face_sets(int tool) return ELEM(tool, SCULPT_TOOL_DRAW_FACE_SETS); } -void SCULPT_stroke_id_ensure(struct Object *ob); -void SCULPT_stroke_id_next(struct Object *ob); +void SCULPT_stroke_id_ensure(Object *ob); +void SCULPT_stroke_id_next(Object *ob); bool SCULPT_tool_can_reuse_automask(int sculpt_tool); -void SCULPT_ensure_valid_pivot(const struct Object *ob, struct Scene *scene); +void SCULPT_ensure_valid_pivot(const Object *ob, Scene *scene); /* -------------------------------------------------------------------- */ /** \name Topology island API @@ -1956,7 +1849,7 @@ void SCULPT_ensure_valid_pivot(const struct Object *ob, struct Scene *scene); */ /* Ensures vertex island keys exist and are valid. */ -void SCULPT_topology_islands_ensure(struct Object *ob); +void SCULPT_topology_islands_ensure(Object *ob); /* Mark vertex island keys as invalid. Call when adding or hiding * geometry. @@ -1968,10 +1861,6 @@ int SCULPT_vertex_island_get(SculptSession *ss, PBVHVertRef vertex); /** \} */ -#ifdef __cplusplus -} -#endif - /* Make SCULPT_ alias to a few blenkernel sculpt methods. */ #define SCULPT_vertex_attr_get BKE_sculpt_vertex_attr_get diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.cc similarity index 85% rename from source/blender/editors/sculpt_paint/sculpt_mask_expand.c rename to source/blender/editors/sculpt_paint/sculpt_mask_expand.cc index 74b3ca95389..fc7971fbde9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.cc @@ -31,12 +31,12 @@ #include "RNA_define.h" #include "ED_screen.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "bmesh.h" -#include -#include +#include +#include static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op) { @@ -70,14 +70,14 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op) SCULPT_filter_cache_free(ss); SCULPT_undo_push_end(ob); SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); } static void sculpt_expand_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; PBVHVertexIter vd; @@ -148,9 +148,9 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * Sculpt *sd = CTX_data_tool_settings(C)->sculpt; ARegion *region = CTX_wm_region(C); float prev_click_f[2]; - copy_v2_v2(prev_click_f, op->customdata); - const int prev_click[2] = {(int)prev_click_f[0], (int)prev_click_f[1]}; - int len = (int)len_v2v2_int(prev_click, event->mval); + copy_v2_v2(prev_click_f, static_cast(op->customdata)); + const int prev_click[2] = {int(prev_click_f[0]), int(prev_click_f[1])}; + int len = int(len_v2v2_int(prev_click, event->mval)); len = abs(len); int mask_speed = RNA_int_get(op->ptr, "mask_speed"); int mask_expand_update_it = len / mask_speed; @@ -161,7 +161,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * if (RNA_boolean_get(op->ptr, "use_cursor")) { SculptCursorGeometryInfo sgi; - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; if (SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) { int active_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, SCULPT_active_vertex_get(ss)); @@ -233,7 +233,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * SCULPT_undo_push_end(ob); SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); return OPERATOR_FINISHED; } @@ -259,16 +259,16 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * ss->face_sets[i] = ss->filter_cache->prev_face_set[i]; } } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .mask_expand_update_it = mask_expand_update_it, - .mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"), - .mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"), - .mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"), - .mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"), - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.mask_expand_update_it = mask_expand_update_it; + data.mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"); + data.mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"); + data.mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"); + data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"); + TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings); @@ -280,16 +280,16 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * return OPERATOR_RUNNING_MODAL; } -typedef struct MaskExpandFloodFillData { +struct MaskExpandFloodFillData { float original_normal[3]; float edge_sensitivity; bool use_normals; -} MaskExpandFloodFillData; +}; static bool mask_expand_floodfill_cb( SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { - MaskExpandFloodFillData *data = userdata; + MaskExpandFloodFillData *data = static_cast(userdata); int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); @@ -337,7 +337,7 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set"); SculptCursorGeometryInfo sgi; - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob); BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd); @@ -347,15 +347,16 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_vertex_random_access_ensure(ss); op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position"); - copy_v2_v2(op->customdata, mval_fl); + copy_v2_v2(static_cast(op->customdata), mval_fl); SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); int vertex_count = SCULPT_vertex_count_get(ss); - ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache"); + ss->filter_cache = MEM_cnew(__func__); - BKE_pbvh_search_gather(pbvh, NULL, NULL, &ss->filter_cache->nodes, &ss->filter_cache->totnode); + BKE_pbvh_search_gather( + pbvh, nullptr, nullptr, &ss->filter_cache->nodes, &ss->filter_cache->totnode); SCULPT_undo_push_begin(ob, op); @@ -372,27 +373,24 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent } } - ss->filter_cache->mask_update_it = MEM_callocN(sizeof(int) * vertex_count, - "mask update iteration"); + ss->filter_cache->mask_update_it = MEM_cnew_array(vertex_count, __func__); if (use_normals) { - ss->filter_cache->normal_factor = MEM_callocN(sizeof(float) * vertex_count, - "mask update normal factor"); - ss->filter_cache->edge_factor = MEM_callocN(sizeof(float) * vertex_count, - "mask update normal factor"); + ss->filter_cache->normal_factor = MEM_cnew_array(vertex_count, __func__); + ss->filter_cache->edge_factor = MEM_cnew_array(vertex_count, __func__); for (int i = 0; i < vertex_count; i++) { ss->filter_cache->edge_factor[i] = 1.0f; } } if (create_face_set) { - ss->filter_cache->prev_face_set = MEM_callocN(sizeof(float) * ss->totfaces, "prev face mask"); + ss->filter_cache->prev_face_set = MEM_cnew_array(ss->totfaces, __func__); for (int i = 0; i < ss->totfaces; i++) { ss->filter_cache->prev_face_set[i] = ss->face_sets ? ss->face_sets[i] : 0; } ss->filter_cache->new_face_set = SCULPT_face_set_next_available_get(ss); } else { - ss->filter_cache->prev_mask = MEM_callocN(sizeof(float) * vertex_count, "prev mask"); + ss->filter_cache->prev_mask = MEM_cnew_array(vertex_count, __func__); for (int i = 0; i < vertex_count; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -412,10 +410,10 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_floodfill_init(ss, &flood); SCULPT_floodfill_add_active(sd, ob, ss, &flood, FLT_MAX); - MaskExpandFloodFillData fdata = { - .use_normals = use_normals, - .edge_sensitivity = RNA_int_get(op->ptr, "edge_sensitivity"), - }; + MaskExpandFloodFillData fdata{}; + fdata.use_normals = use_normals; + fdata.edge_sensitivity = RNA_int_get(op->ptr, "edge_sensitivity"); + SCULPT_active_vertex_normal_get(ss, fdata.original_normal); SCULPT_floodfill_execute(ss, &flood, mask_expand_floodfill_cb, &fdata); SCULPT_floodfill_free(&flood); @@ -438,16 +436,16 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent MEM_SAFE_FREE(ss->filter_cache->edge_factor); } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .mask_expand_update_it = 0, - .mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"), - .mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"), - .mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"), - .mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"), - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.mask_expand_update_it = 0; + data.mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"); + data.mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"); + data.mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"); + data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"); + TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings); diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.c b/source/blender/editors/sculpt_paint/sculpt_mask_init.cc similarity index 90% rename from source/blender/editors/sculpt_paint/sculpt_mask_init.c rename to source/blender/editors/sculpt_paint/sculpt_mask_init.cc index a4f29fd758a..8d35ea10106 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_init.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.cc @@ -32,21 +32,21 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "bmesh.h" -#include -#include +#include +#include /* Mask Init operator. */ /* Initializes mask values for the entire mesh depending on the mode. */ -typedef enum eSculptMaskInitMode { +enum eSculptMaskInitMode { SCULPT_MASK_INIT_RANDOM_PER_VERTEX, SCULPT_MASK_INIT_RANDOM_PER_FACE_SET, SCULPT_MASK_INIT_RANDOM_PER_LOOSE_PART, -} eSculptMaskInitMode; +}; static EnumPropertyItem prop_sculpt_mask_init_mode_types[] = { { @@ -70,14 +70,14 @@ static EnumPropertyItem prop_sculpt_mask_init_mode_types[] = { "Random per Loose Part", "", }, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static void mask_init_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; PBVHVertexIter vd; @@ -119,7 +119,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op) PBVH *pbvh = ob->sculpt->pbvh; PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); if (totnode == 0) { return OPERATOR_CANCELLED; @@ -131,12 +131,11 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op) SCULPT_topology_islands_ensure(ob); } - SculptThreadedTaskData data = { - .ob = ob, - .nodes = nodes, - .mask_init_mode = mode, - .mask_init_seed = PIL_check_seconds_timer(), - }; + SculptThreadedTaskData data{}; + data.ob = ob; + data.nodes = nodes; + data.mask_init_mode = mode; + data.mask_init_seed = PIL_check_seconds_timer(); TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc similarity index 92% rename from source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c rename to source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc index ccee7814f83..86ac514898e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc @@ -17,30 +17,31 @@ #include "BKE_paint.h" #include "BKE_pbvh.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "GPU_immediate.h" #include "GPU_matrix.h" #include "bmesh.h" -#include -#include +#include +#include -typedef struct MultiplaneScrapeSampleData { +struct MultiplaneScrapeSampleData { float area_cos[2][3]; float area_nos[2][3]; int area_count[2]; -} MultiplaneScrapeSampleData; +}; static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; - MultiplaneScrapeSampleData *mssd = tls->userdata_chunk; + MultiplaneScrapeSampleData *mssd = static_cast( + tls->userdata_chunk); float(*mat)[4] = data->mat; PBVHVertexIter vd; @@ -98,12 +99,12 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, } } -static void calc_multiplane_scrape_surface_reduce(const void *__restrict UNUSED(userdata), +static void calc_multiplane_scrape_surface_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - MultiplaneScrapeSampleData *join = chunk_join; - MultiplaneScrapeSampleData *mssd = chunk; + MultiplaneScrapeSampleData *join = static_cast(chunk_join); + MultiplaneScrapeSampleData *mssd = static_cast(chunk); add_v3_v3(join->area_cos[0], mssd->area_cos[0]); add_v3_v3(join->area_cos[1], mssd->area_cos[1]); @@ -119,7 +120,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; float(*mat)[4] = data->mat; @@ -275,14 +276,13 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, if (brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_DYNAMIC) { /* Sample the individual normal and area center of the two areas at both sides of the cursor. */ - SculptThreadedTaskData sample_data = { - .sd = NULL, - .ob = ob, - .brush = brush, - .nodes = nodes, - .totnode = totnode, - .mat = mat, - }; + SculptThreadedTaskData sample_data{}; + sample_data.sd = nullptr; + sample_data.ob = ob; + sample_data.brush = brush; + sample_data.nodes = nodes; + sample_data.totnode = totnode; + sample_data.mat = mat; MultiplaneScrapeSampleData mssd = {{{0}}}; @@ -302,13 +302,13 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, /* Use the area center of both planes to detect if we are sculpting along a concave or convex * edge. */ - mul_v3_v3fl(sampled_plane_co[0], mssd.area_cos[0], 1.0f / (float)mssd.area_count[0]); - mul_v3_v3fl(sampled_plane_co[1], mssd.area_cos[1], 1.0f / (float)mssd.area_count[1]); + mul_v3_v3fl(sampled_plane_co[0], mssd.area_cos[0], 1.0f / float(mssd.area_count[0])); + mul_v3_v3fl(sampled_plane_co[1], mssd.area_cos[1], 1.0f / float(mssd.area_count[1])); mid_v3_v3v3(mid_co, sampled_plane_co[0], sampled_plane_co[1]); /* Calculate the scrape planes angle based on the sampled normals. */ - mul_v3_v3fl(sampled_plane_normals[0], mssd.area_nos[0], 1.0f / (float)mssd.area_count[0]); - mul_v3_v3fl(sampled_plane_normals[1], mssd.area_nos[1], 1.0f / (float)mssd.area_count[1]); + mul_v3_v3fl(sampled_plane_normals[0], mssd.area_nos[0], 1.0f / float(mssd.area_count[0])); + mul_v3_v3fl(sampled_plane_normals[1], mssd.area_nos[1], 1.0f / float(mssd.area_count[1])); normalize_v3(sampled_plane_normals[0]); normalize_v3(sampled_plane_normals[1]); @@ -347,14 +347,13 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, } } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .mat = mat, - .multiplane_scrape_angle = ss->cache->multiplane_scrape_angle, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.mat = mat; + data.multiplane_scrape_angle = ss->cache->multiplane_scrape_angle; /* Calculate the final left and right scrape planes. */ float plane_no[3]; diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.cc similarity index 90% rename from source/blender/editors/sculpt_paint/sculpt_ops.c rename to source/blender/editors/sculpt_paint/sculpt_ops.cc index 35fd8ffc663..d9738b11215 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -57,7 +57,7 @@ #include "ED_sculpt.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" @@ -67,13 +67,13 @@ #include "bmesh.h" -#include -#include -#include +#include +#include +#include /* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */ -static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_set_persistent_base_exec(bContext *C, wmOperator * /*op*/) { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Object *ob = CTX_data_active_object(C); @@ -127,7 +127,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot) /************************* SCULPT_OT_optimize *************************/ -static int sculpt_optimize_exec(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_optimize_exec(bContext *C, wmOperator * /*op*/) { Object *ob = CTX_data_active_object(C); @@ -180,7 +180,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op) } switch (BKE_pbvh_type(pbvh)) { - case PBVH_BMESH: + case PBVH_BMESH: { /* Dyntopo Symmetrize. */ /* To simplify undo for symmetrize, all BMesh elements are logged @@ -188,7 +188,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op) * are logged as added (as opposed to attempting to store just the * parts that symmetrize modifies). */ SCULPT_undo_push_begin(ob, op); - SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_SYMMETRIZE); + SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_DYNTOPO_SYMMETRIZE); BM_log_before_all_removed(ss->bm, ss->bm_log); BM_mesh_toolflags_set(ss->bm, true); @@ -212,17 +212,19 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op) SCULPT_undo_push_end(ob); break; - case PBVH_FACES: + } + case PBVH_FACES: { /* Mesh Symmetrize. */ ED_sculpt_undo_geometry_begin(ob, op); - Mesh *mesh = ob->data; + Mesh *mesh = static_cast(ob->data); BKE_mesh_mirror_apply_mirror_on_axis(bmain, mesh, sd->symmetrize_direction, dist); ED_sculpt_undo_geometry_end(ob); - BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL); break; + } case PBVH_GRIDS: return OPERATOR_CANCELLED; } @@ -266,10 +268,10 @@ static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene, BKE_sculpt_toolsettings_data_ensure(scene); /* Create sculpt mode session data. */ - if (ob->sculpt != NULL) { + if (ob->sculpt != nullptr) { BKE_sculptsession_free(ob); } - ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); + ob->sculpt = MEM_cnew(__func__); ob->sculpt->mode_type = OB_MODE_SCULPT; /* Trigger evaluation of modifier stack to ensure @@ -359,11 +361,11 @@ void ED_object_sculptmode_enter_ex(Main *bmain, if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) { MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); - const char *message_unsupported = NULL; + const char *message_unsupported = nullptr; if (me->totloop != me->totpoly * 3) { message_unsupported = TIP_("non-triangle face"); } - else if (mmd != NULL) { + else if (mmd != nullptr) { message_unsupported = TIP_("multi-res modifier"); } else { @@ -388,17 +390,17 @@ void ED_object_sculptmode_enter_ex(Main *bmain, } } - if ((message_unsupported == NULL) || force_dyntopo) { + if ((message_unsupported == nullptr) || force_dyntopo) { /* Needed because we may be entering this mode before the undo system loads. */ - wmWindowManager *wm = bmain->wm.first; - bool has_undo = wm->undo_stack != NULL; + wmWindowManager *wm = static_cast(bmain->wm.first); + bool has_undo = wm->undo_stack != nullptr; /* Undo push is needed to prevent memory leak. */ if (has_undo) { SCULPT_undo_push_begin_ex(ob, "Dynamic topology enable"); } SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob); if (has_undo) { - SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); + SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_DYNTOPO_BEGIN); SCULPT_undo_push_end(ob); } } @@ -415,7 +417,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain, DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); } -void ED_object_sculptmode_enter(struct bContext *C, Depsgraph *depsgraph, ReportList *reports) +void ED_object_sculptmode_enter(bContext *C, Depsgraph *depsgraph, ReportList *reports) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -480,7 +482,7 @@ void ED_object_sculptmode_exit(bContext *C, Depsgraph *depsgraph) static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) { - struct wmMsgBus *mbus = CTX_wm_message_bus(C); + wmMsgBus *mbus = CTX_wm_message_bus(C); Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); Scene *scene = CTX_data_scene(C); @@ -492,7 +494,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) const bool is_mode_set = (ob->mode & mode_flag) != 0; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, ob, eObjectMode(mode_flag), op->reports)) { return OPERATOR_CANCELLED; } } @@ -508,11 +510,11 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) BKE_paint_toolslots_brush_validate(bmain, &ts->sculpt->paint); if (ob->mode & mode_flag) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); /* Dyntopo adds its own undo step. */ if ((me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) == 0) { /* Without this the memfile undo step is used, - * while it works it causes lag when undoing the first undo step, see T71564. */ + * while it works it causes lag when undoing the first undo step, see #71564. */ wmWindowManager *wm = CTX_wm_manager(C); if (wm->op_undo_depth <= 1) { SCULPT_undo_push_begin(ob, op); @@ -580,8 +582,8 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float /* Assuming an average of 6 edges per vertex in a triangulated mesh. */ const int max_preview_verts = SCULPT_vertex_count_get(ss) * 3 * 2; - if (ss->preview_vert_list == NULL) { - ss->preview_vert_list = MEM_callocN(max_preview_verts * sizeof(PBVHVertRef), "preview lines"); + if (ss->preview_vert_list == nullptr) { + ss->preview_vert_list = MEM_cnew_array(max_preview_verts, __func__); } GSQueue *non_visited_verts = BLI_gsqueue_new(sizeof(PBVHVertRef)); @@ -621,7 +623,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float ss->preview_vert_count = totpoints; } -static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e)) +static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Scene *scene = CTX_data_scene(C); @@ -718,17 +720,18 @@ static float sculpt_mask_by_color_final_mask_get(const float current_mask, return new_mask; } -typedef struct MaskByColorContiguousFloodFillData { +struct MaskByColorContiguousFloodFillData { float threshold; bool invert; float *new_mask; float initial_color[3]; -} MaskByColorContiguousFloodFillData; +}; -static void do_mask_by_color_contiguous_update_nodes_cb( - void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) +static void do_mask_by_color_contiguous_update_nodes_cb(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK); @@ -759,7 +762,8 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb( int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - MaskByColorContiguousFloodFillData *data = userdata; + MaskByColorContiguousFloodFillData *data = static_cast( + userdata); float current_color[4]; SCULPT_vertex_color_get(ss, to_v, current_color); @@ -786,7 +790,7 @@ static void sculpt_mask_by_color_contiguous(Object *object, SculptSession *ss = object->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *new_mask = MEM_calloc_arrayN(totvert, sizeof(float), "new mask"); + float *new_mask = MEM_cnew_array(totvert, __func__); if (invert) { for (int i = 0; i < totvert; i++) { @@ -813,17 +817,16 @@ static void sculpt_mask_by_color_contiguous(Object *object, int totnode; PBVHNode **nodes; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - SculptThreadedTaskData data = { - .ob = object, - .nodes = nodes, - .mask_by_color_floodfill = new_mask, - .mask_by_color_vertex = vertex, - .mask_by_color_threshold = threshold, - .mask_by_color_invert = invert, - .mask_by_color_preserve_mask = preserve_mask, - }; + SculptThreadedTaskData data{}; + data.ob = object; + data.nodes = nodes; + data.mask_by_color_floodfill = new_mask; + data.mask_by_color_vertex = vertex; + data.mask_by_color_threshold = threshold; + data.mask_by_color_invert = invert; + data.mask_by_color_preserve_mask = preserve_mask; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -837,9 +840,9 @@ static void sculpt_mask_by_color_contiguous(Object *object, static void do_mask_by_color_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK); @@ -882,16 +885,15 @@ static void sculpt_mask_by_color_full_mesh(Object *object, int totnode; PBVHNode **nodes; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - SculptThreadedTaskData data = { - .ob = object, - .nodes = nodes, - .mask_by_color_vertex = vertex, - .mask_by_color_threshold = threshold, - .mask_by_color_invert = invert, - .mask_by_color_preserve_mask = preserve_mask, - }; + SculptThreadedTaskData data{}; + data.ob = object; + data.nodes = nodes; + data.mask_by_color_vertex = vertex; + data.mask_by_color_threshold = threshold; + data.mask_by_color_invert = invert; + data.mask_by_color_preserve_mask = preserve_mask; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -924,7 +926,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven /* Tools that are not brushes do not have the brush gizmo to update the vertex as the mouse move, * so it needs to be updated here. */ SculptCursorGeometryInfo sgi; - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); SCULPT_undo_push_begin(ob, op); @@ -990,34 +992,34 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot) 1.0f); } -typedef enum { +enum CavityBakeMixMode { AUTOMASK_BAKE_MIX, AUTOMASK_BAKE_MULTIPLY, AUTOMASK_BAKE_DIVIDE, AUTOMASK_BAKE_ADD, AUTOMASK_BAKE_SUBTRACT, -} CavityBakeMixMode; +}; -typedef enum { +enum CavityBakeSettingsSource { AUTOMASK_SETTINGS_OPERATOR, AUTOMASK_SETTINGS_SCENE, AUTOMASK_SETTINGS_BRUSH -} CavityBakeSettingsSource; +}; -typedef struct AutomaskBakeTaskData { +struct AutomaskBakeTaskData { SculptSession *ss; AutomaskingCache *automasking; PBVHNode **nodes; CavityBakeMixMode mode; float factor; Object *ob; -} AutomaskBakeTaskData; +}; static void sculpt_bake_cavity_exec_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - AutomaskBakeTaskData *tdata = userdata; + AutomaskBakeTaskData *tdata = static_cast(userdata); SculptSession *ss = tdata->ss; PBVHNode *node = tdata->nodes[n]; PBVHVertexIter vd; @@ -1072,7 +1074,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); + const Brush *brush = BKE_paint_brush(&sd->paint); MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob); BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd); @@ -1082,13 +1084,13 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) SCULPT_undo_push_begin(ob, op); - CavityBakeMixMode mode = RNA_enum_get(op->ptr, "mix_mode"); + CavityBakeMixMode mode = CavityBakeMixMode(RNA_enum_get(op->ptr, "mix_mode")); float factor = RNA_float_get(op->ptr, "mix_factor"); PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); AutomaskBakeTaskData tdata; @@ -1096,9 +1098,9 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) */ Sculpt sd2 = *sd; - CavityBakeSettingsSource source = (CavityBakeSettingsSource)RNA_enum_get(op->ptr, - "settings_source"); - switch (source) { + CavityBakeSettingsSource src = (CavityBakeSettingsSource)RNA_enum_get(op->ptr, + "settings_source"); + switch (src) { case AUTOMASK_SETTINGS_OPERATOR: if (RNA_boolean_get(op->ptr, "invert")) { sd2.automasking_flags = BRUSH_AUTOMASKING_CAVITY_INVERTED; @@ -1146,7 +1148,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) } /* Create copy of brush with cleared automasking settings. */ - Brush brush2 = *brush; + Brush brush2 = blender::dna::shallow_copy(*brush); brush2.automasking_flags = 0; brush2.automasking_boundary_edges_propagation_steps = 1; brush2.automasking_cavity_curve = sd2.automasking_cavity_curve; @@ -1180,7 +1182,7 @@ static void cavity_bake_ui(bContext *C, wmOperator *op) { uiLayout *layout = op->layout; Scene *scene = CTX_data_scene(C); - Sculpt *sd = scene->toolsettings ? scene->toolsettings->sculpt : NULL; + Sculpt *sd = scene->toolsettings ? scene->toolsettings->sculpt : nullptr; uiLayoutSetPropSep(layout, true); uiLayoutSetPropDecorate(layout, false); @@ -1193,13 +1195,13 @@ static void cavity_bake_ui(bContext *C, wmOperator *op) switch (source) { case AUTOMASK_SETTINGS_OPERATOR: { - uiItemR(layout, op->ptr, "mix_mode", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "mix_factor", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "settings_source", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "factor", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "blur_steps", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "invert", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "use_curve", 0, NULL, ICON_NONE); + uiItemR(layout, op->ptr, "mix_mode", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "mix_factor", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "settings_source", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "factor", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "blur_steps", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "invert", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "use_curve", 0, nullptr, ICON_NONE); if (sd && RNA_boolean_get(op->ptr, "use_curve")) { PointerRNA sculpt_ptr; @@ -1212,9 +1214,9 @@ static void cavity_bake_ui(bContext *C, wmOperator *op) } case AUTOMASK_SETTINGS_BRUSH: case AUTOMASK_SETTINGS_SCENE: - uiItemR(layout, op->ptr, "mix_mode", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "mix_factor", 0, NULL, ICON_NONE); - uiItemR(layout, op->ptr, "settings_source", 0, NULL, ICON_NONE); + uiItemR(layout, op->ptr, "mix_mode", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "mix_factor", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "settings_source", 0, nullptr, ICON_NONE); break; } @@ -1234,7 +1236,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) {AUTOMASK_BAKE_DIVIDE, "DIVIDE", ICON_NONE, "Divide", ""}, {AUTOMASK_BAKE_ADD, "ADD", ICON_NONE, "Add", ""}, {AUTOMASK_BAKE_SUBTRACT, "SUBTRACT", ICON_NONE, "Subtract", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* api callbacks */ @@ -1254,7 +1256,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) "Use settings from operator properties"}, {AUTOMASK_SETTINGS_BRUSH, "BRUSH", ICON_NONE, "Brush", "Use settings from brush"}, {AUTOMASK_SETTINGS_SCENE, "SCENE", ICON_NONE, "Scene", "Use settings from scene"}, - {0, NULL, 0, NULL, NULL}}; + {0, nullptr, 0, nullptr, nullptr}}; RNA_def_enum(ot->srna, "settings_source", @@ -1304,7 +1306,7 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) int totnode; bool with_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); if (!totnode) { return OPERATOR_CANCELLED; @@ -1330,7 +1332,7 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) * reduced memory usage without manually clearing it later, and allows sculpt operations to * avoid checking element's hide status. */ CustomData_free_layer_named(&mesh->pdata, ".hide_poly", mesh->totpoly); - ss->hide_poly = NULL; + ss->hide_poly = nullptr; } else { SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_HIDDEN); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.cc similarity index 91% rename from source/blender/editors/sculpt_paint/sculpt_paint_color.c rename to source/blender/editors/sculpt_paint/sculpt_paint_color.cc index 3a6f7319bdf..1096639fe95 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.cc @@ -23,20 +23,20 @@ #include "IMB_colormanagement.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "IMB_imbuf.h" #include "bmesh.h" -#include -#include +#include +#include static void do_color_smooth_task_cb_exec(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = ss->cache->bstrength; @@ -85,7 +85,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = fabsf(ss->cache->bstrength); @@ -168,7 +168,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, float noise = 1.0f; const float density = ss->cache->paint_brush.density; if (density < 1.0f) { - const float hash_noise = (float)BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index); + const float hash_noise = float(BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index)); if (hash_noise > density) { noise = density * hash_noise; fade = fade * noise; @@ -196,25 +196,25 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, float col[4]; SCULPT_vertex_color_get(ss, vd.vertex, col); - IMB_blend_color_float(col, orig_data.col, buffer_color, brush->blend); + IMB_blend_color_float(col, orig_data.col, buffer_color, IMB_BlendMode(brush->blend)); CLAMP4(col, 0.0f, 1.0f); SCULPT_vertex_color_set(ss, vd.vertex, col); } BKE_pbvh_vertex_iter_end; } -typedef struct SampleWetPaintTLSData { +struct SampleWetPaintTLSData { int tot_samples; float color[4]; -} SampleWetPaintTLSData; +}; static void do_sample_wet_paint_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; - SampleWetPaintTLSData *swptd = tls->userdata_chunk; + SampleWetPaintTLSData *swptd = static_cast(tls->userdata_chunk); PBVHVertexIter vd; SculptBrushTest test; @@ -238,12 +238,12 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata), +static void sample_wet_paint_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - SampleWetPaintTLSData *join = chunk_join; - SampleWetPaintTLSData *swptd = chunk; + SampleWetPaintTLSData *join = static_cast(chunk_join); + SampleWetPaintTLSData *swptd = static_cast(chunk); join->tot_samples += swptd->tot_samples; add_v4_v4(join->color, swptd->color); @@ -271,7 +271,7 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { if (SCULPT_stroke_is_first_brush_step(ss->cache)) { - ss->cache->density_seed = (float)BLI_hash_int_01(ss->cache->location[0] * 1000); + ss->cache->density_seed = float(BLI_hash_int_01(ss->cache->location[0] * 1000)); } return; } @@ -309,13 +309,12 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, /* Smooth colors mode. */ if (ss->cache->alt_smooth) { - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .mat = mat, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.mat = mat; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -328,12 +327,11 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, /* Wet paint color sampling. */ float wet_color[4] = {0.0f}; if (ss->cache->paint_brush.wet_mix > 0.0f) { - SculptThreadedTaskData task_data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .brush = brush, - }; + SculptThreadedTaskData task_data{}; + task_data.sd = sd; + task_data.ob = ob; + task_data.nodes = nodes; + task_data.brush = brush; SampleWetPaintTLSData swptd; swptd.tot_samples = 0; @@ -364,14 +362,13 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, } /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .wet_mix_sampled_color = wet_color, - .mat = mat, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.wet_mix_sampled_color = wet_color; + data.mat = mat; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -382,7 +379,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = ss->cache->bstrength; @@ -533,9 +530,9 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHVertexIter vd; @@ -557,7 +554,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode const int totvert = SCULPT_vertex_count_get(ss); if (!ss->cache->prev_colors) { - ss->cache->prev_colors = MEM_callocN(sizeof(float[4]) * totvert, "prev colors"); + ss->cache->prev_colors = MEM_cnew_array(totvert, __func__); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -567,12 +564,11 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode BKE_curvemapping_init(brush->curve); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index d9e982f4ff8..5d7c4687bc1 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -26,7 +26,7 @@ #include "bmesh.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" namespace blender::ed::sculpt_paint::paint::image { @@ -514,8 +514,6 @@ static void do_mark_dirty_regions(void *__restrict userdata, } // namespace blender::ed::sculpt_paint::paint::image -extern "C" { - using namespace blender::ed::sculpt_paint::paint::image; bool SCULPT_paint_image_canvas_get(PaintModeSettings *paint_mode_settings, @@ -576,4 +574,3 @@ void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, BKE_pbvh_parallel_range_settings(&settings_flush, false, texnodes_num); BLI_task_parallel_range(0, texnodes_num, &data, do_mark_dirty_regions, &settings_flush); } -} diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.cc similarity index 90% rename from source/blender/editors/sculpt_paint/sculpt_pose.c rename to source/blender/editors/sculpt_paint/sculpt_pose.cc index 389a548fb2d..0dfbe7c59a2 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.cc @@ -22,12 +22,12 @@ #include "BKE_pbvh.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "bmesh.h" -#include -#include +#include +#include static void pose_solve_ik_chain(SculptPoseIKChain *ik_chain, const float initial_target[3], @@ -136,9 +136,9 @@ static void pose_solve_scale_chain(SculptPoseIKChain *ik_chain, const float scal static void do_pose_brush_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain; SculptPoseIKChainSegment *segments = ik_chain->segments; @@ -169,9 +169,9 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, /* Get the transform matrix for the vertex symmetry area to calculate a displacement in the * vertex. */ - mul_m4_v3(segments[ik].pivot_mat_inv[(int)symm_area], new_co); - mul_m4_v3(segments[ik].trans_mat[(int)symm_area], new_co); - mul_m4_v3(segments[ik].pivot_mat[(int)symm_area], new_co); + mul_m4_v3(segments[ik].pivot_mat_inv[int(symm_area)], new_co); + mul_m4_v3(segments[ik].trans_mat[int(symm_area)], new_co); + mul_m4_v3(segments[ik].pivot_mat[int(symm_area)], new_co); /* Apply the segment weight of the vertex to the displacement. */ sub_v3_v3v3(disp, new_co, orig_data.co); @@ -200,17 +200,17 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -typedef struct PoseGrowFactorTLSData { +struct PoseGrowFactorTLSData { float pos_avg[3]; int pos_count; -} PoseGrowFactorTLSData; +}; static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; - PoseGrowFactorTLSData *gftd = tls->userdata_chunk; + SculptThreadedTaskData *data = static_cast(userdata); + PoseGrowFactorTLSData *gftd = static_cast(tls->userdata_chunk); SculptSession *ss = data->ob->sculpt; const char symm = SCULPT_mesh_symmetry_xyz_get(data->ob); PBVHVertexIter vd; @@ -238,12 +238,12 @@ static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void pose_brush_grow_factor_reduce(const void *__restrict UNUSED(userdata), +static void pose_brush_grow_factor_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - PoseGrowFactorTLSData *join = chunk_join; - PoseGrowFactorTLSData *gftd = chunk; + PoseGrowFactorTLSData *join = static_cast(chunk_join); + PoseGrowFactorTLSData *gftd = static_cast(chunk); add_v3_v3(join->pos_avg, gftd->pos_avg); join->pos_count += gftd->pos_count; } @@ -263,14 +263,13 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, PBVH *pbvh = ob->sculpt->pbvh; int totnode; - BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .totnode = totnode, - .pose_factor = pose_factor, - }; + BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = nodes; + data.totnode = totnode; + data.pose_factor = pose_factor; data.pose_initial_co = pose_target; TaskParallelSettings settings; @@ -284,7 +283,8 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, bool grow_next_iteration = true; float prev_len = FLT_MAX; - data.prev_mask = MEM_mallocN(SCULPT_vertex_count_get(ss) * sizeof(float), "prev mask"); + data.prev_mask = static_cast( + MEM_malloc_arrayN(SCULPT_vertex_count_get(ss), sizeof(float), __func__)); while (grow_next_iteration) { zero_v3(gftd.pos_avg); gftd.pos_count = 0; @@ -292,7 +292,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, BLI_task_parallel_range(0, totnode, &data, pose_brush_grow_factor_task_cb_ex, &settings); if (gftd.pos_count != 0) { - mul_v3_fl(gftd.pos_avg, 1.0f / (float)gftd.pos_count); + mul_v3_fl(gftd.pos_avg, 1.0f / float(gftd.pos_count)); if (pose_origin) { /* Test with pose origin. Used when growing the factors to compensate the Origin Offset. */ /* Stop when the factor's avg_pos starts moving away from the origin instead of getting @@ -344,7 +344,7 @@ static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3 for (char i = 0; i <= symm; ++i) { if (SCULPT_is_symmetry_iteration_valid(i, symm)) { float location[3]; - flip_v3_v3(location, br_co, (char)i); + flip_v3_v3(location, br_co, ePaintSymmetryFlags(i)); if (len_v3v3(location, vertex) < radius) { return true; } @@ -353,7 +353,7 @@ static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3 return false; } -typedef struct PoseFloodFillData { +struct PoseFloodFillData { float pose_initial_co[3]; float radius; int symm; @@ -393,17 +393,14 @@ typedef struct PoseFloodFillData { int masked_face_set_it; int masked_face_set; int target_face_set; -} PoseFloodFillData; +}; -static bool pose_topology_floodfill_cb(SculptSession *ss, - PBVHVertRef UNUSED(from_v), - PBVHVertRef to_v, - bool is_duplicate, - void *userdata) +static bool pose_topology_floodfill_cb( + SculptSession *ss, PBVHVertRef /*from_v*/, PBVHVertRef to_v, bool is_duplicate, void *userdata) { int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - PoseFloodFillData *data = userdata; + PoseFloodFillData *data = static_cast(userdata); const float *co = SCULPT_vertex_co_get(ss, to_v); if (data->pose_factor) { @@ -429,13 +426,10 @@ static bool pose_topology_floodfill_cb(SculptSession *ss, return false; } -static bool pose_face_sets_floodfill_cb(SculptSession *ss, - PBVHVertRef UNUSED(from_v), - PBVHVertRef to_v, - bool is_duplicate, - void *userdata) +static bool pose_face_sets_floodfill_cb( + SculptSession *ss, PBVHVertRef /*from_v*/, PBVHVertRef to_v, bool is_duplicate, void *userdata) { - PoseFloodFillData *data = userdata; + PoseFloodFillData *data = static_cast(userdata); const int index = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); const PBVHVertRef vertex = to_v; @@ -547,12 +541,12 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd, SCULPT_floodfill_init(ss, &flood); SCULPT_floodfill_add_active(sd, ob, ss, &flood, (r_pose_factor) ? radius : 0.0f); - PoseFloodFillData fdata = { - .radius = radius, - .symm = SCULPT_mesh_symmetry_xyz_get(ob), - .pose_factor = r_pose_factor, - .tot_co = 0, - }; + PoseFloodFillData fdata{}; + fdata.radius = radius; + fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob); + fdata.pose_factor = r_pose_factor; + fdata.tot_co = 0; + zero_v3(fdata.pose_origin); copy_v3_v3(fdata.pose_initial_co, initial_location); copy_v3_v3(fdata.fallback_floodfill_origin, initial_location); @@ -560,7 +554,7 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd, SCULPT_floodfill_free(&flood); if (fdata.tot_co > 0) { - mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co); + mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co)); } else { copy_v3_v3(fdata.pose_origin, fdata.fallback_floodfill_origin); @@ -577,15 +571,15 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd, */ if (pose_offset != 0.0f && r_pose_factor) { sculpt_pose_grow_pose_factor( - sd, ob, ss, fdata.pose_origin, fdata.pose_origin, 0, NULL, r_pose_factor); + sd, ob, ss, fdata.pose_origin, fdata.pose_origin, 0, nullptr, r_pose_factor); } } static void pose_brush_init_task_cb_ex(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { @@ -608,12 +602,11 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata, /* Init the IK chain with empty weights. */ static SculptPoseIKChain *pose_ik_chain_new(const int totsegments, const int totverts) { - SculptPoseIKChain *ik_chain = MEM_callocN(sizeof(SculptPoseIKChain), "Pose IK Chain"); + SculptPoseIKChain *ik_chain = MEM_cnew(__func__); ik_chain->tot_segments = totsegments; - ik_chain->segments = MEM_callocN(totsegments * sizeof(SculptPoseIKChainSegment), - "Pose IK Chain Segments"); + ik_chain->segments = MEM_cnew_array(totsegments, __func__); for (int i = 0; i < totsegments; i++) { - ik_chain->segments[i].weights = MEM_callocN(totverts * sizeof(float), "Pose IK weights"); + ik_chain->segments[i].weights = MEM_cnew_array(totverts, __func__); } return ik_chain; } @@ -674,11 +667,10 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd, * added to the IK chain. */ /* This stores the whole pose factors values as they grow through the mesh. */ - float *pose_factor_grow = MEM_callocN(totvert * sizeof(float), "Pose Factor Grow"); + float *pose_factor_grow = MEM_cnew_array(totvert, __func__); /* This stores the previous status of the factors when growing a new iteration. */ - float *pose_factor_grow_prev = MEM_callocN(totvert * sizeof(float), - "Pose Factor Grow Prev Iteration"); + float *pose_factor_grow_prev = MEM_cnew_array(totvert, __func__); pose_factor_grow[nearest_vertex_index] = 1.0f; @@ -712,7 +704,7 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd, sculpt_pose_grow_pose_factor(sd, ob, ss, - NULL, + nullptr, next_chain_segment_target, chain_segment_len, ik_chain->segments[i].orig, @@ -763,19 +755,19 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( BLI_gset_add(visited_face_sets, POINTER_FROM_INT(current_face_set)); - PoseFloodFillData fdata = { - .radius = radius, - .symm = SCULPT_mesh_symmetry_xyz_get(ob), - .pose_factor = ik_chain->segments[s].weights, - .tot_co = 0, - .fallback_count = 0, - .current_face_set = current_face_set, - .prev_face_set = prev_face_set, - .visited_face_sets = visited_face_sets, - .is_weighted = is_weighted, - .next_face_set_found = false, - .is_first_iteration = s == 0, - }; + PoseFloodFillData fdata{}; + fdata.radius = radius; + fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob); + fdata.pose_factor = ik_chain->segments[s].weights; + fdata.tot_co = 0; + fdata.fallback_count = 0; + fdata.current_face_set = current_face_set; + fdata.prev_face_set = prev_face_set; + fdata.visited_face_sets = visited_face_sets; + fdata.is_weighted = is_weighted; + fdata.next_face_set_found = false; + fdata.is_first_iteration = s == 0; + zero_v3(fdata.pose_origin); zero_v3(fdata.fallback_origin); copy_v3_v3(fdata.pose_initial_co, SCULPT_vertex_co_get(ss, current_vertex)); @@ -783,11 +775,11 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( SCULPT_floodfill_free(&flood); if (fdata.tot_co > 0) { - mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co); + mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co)); copy_v3_v3(ik_chain->segments[s].orig, fdata.pose_origin); } else if (fdata.fallback_count > 0) { - mul_v3_fl(fdata.fallback_origin, 1.0f / (float)fdata.fallback_count); + mul_v3_fl(fdata.fallback_origin, 1.0f / float(fdata.fallback_count)); copy_v3_v3(ik_chain->segments[s].orig, fdata.fallback_origin); } else { @@ -799,7 +791,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( current_vertex = fdata.next_vertex; } - BLI_gset_free(visited_face_sets, NULL); + BLI_gset_free(visited_face_sets, nullptr); pose_ik_chain_origin_heads_init(ik_chain, SCULPT_active_vertex_co_get(ss)); @@ -811,7 +803,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( static bool pose_face_sets_fk_find_masked_floodfill_cb( SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { - PoseFloodFillData *data = userdata; + PoseFloodFillData *data = static_cast(userdata); int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); @@ -846,12 +838,12 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb( } static bool pose_face_sets_fk_set_weights_floodfill_cb(SculptSession *ss, - PBVHVertRef UNUSED(from_v), + PBVHVertRef /*from_v*/, PBVHVertRef to_v, - bool UNUSED(is_duplicate), + bool /*is_duplicate*/, void *userdata) { - PoseFloodFillData *data = userdata; + PoseFloodFillData *data = static_cast(userdata); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); @@ -875,7 +867,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( SCULPT_floodfill_init(ss, &flood); SCULPT_floodfill_add_initial(&flood, active_vertex); PoseFloodFillData fdata; - fdata.floodfill_it = MEM_calloc_arrayN(totvert, sizeof(int), "floodfill iteration"); + fdata.floodfill_it = static_cast(MEM_calloc_arrayN(totvert, sizeof(int), __func__)); fdata.floodfill_it[active_vertex_index] = 1; fdata.initial_face_set = active_face_set; fdata.masked_face_set = SCULPT_FACE_SET_NONE; @@ -884,7 +876,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( fdata.visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", 3); SCULPT_floodfill_execute(ss, &flood, pose_face_sets_fk_find_masked_floodfill_cb, &fdata); SCULPT_floodfill_free(&flood); - BLI_gset_free(fdata.visited_face_sets, NULL); + BLI_gset_free(fdata.visited_face_sets, nullptr); int origin_count = 0; float origin_acc[3] = {0.0f}; @@ -950,7 +942,7 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd, const float initial_location[3], const float radius) { - SculptPoseIKChain *ik_chain = NULL; + SculptPoseIKChain *ik_chain = nullptr; const bool use_fake_neighbors = !(br->flag2 & BRUSH_USE_CONNECTED_ONLY); @@ -984,14 +976,13 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br PBVH *pbvh = ob->sculpt->pbvh; int totnode; - BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = br, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = br; + data.nodes = nodes; /* Init the IK chain that is going to be used to deform the vertices. */ ss->cache->pose_ik_chain = SCULPT_pose_ik_chain_init( @@ -1094,7 +1085,7 @@ static void sculpt_pose_do_scale_translate_deform(SculptSession *ss, Brush *brus } } -static void sculpt_pose_do_squash_stretch_deform(SculptSession *ss, Brush *UNUSED(brush)) +static void sculpt_pose_do_squash_stretch_deform(SculptSession *ss, Brush * /*brush*/) { float ik_target[3]; SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain; @@ -1169,7 +1160,7 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float symm_orig[3]; float symm_initial_orig[3]; - ePaintSymmetryAreas symm_area = symm_it; + ePaintSymmetryAreas symm_area = ePaintSymmetryAreas(symm_it); copy_qt_qt(symm_rot, ik_chain->segments[i].rot); copy_v3_v3(symm_orig, ik_chain->segments[i].orig); @@ -1218,12 +1209,11 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) } } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.cc similarity index 94% rename from source/blender/editors/sculpt_paint/sculpt_smooth.c rename to source/blender/editors/sculpt_paint/sculpt_smooth.cc index 5af8381f6da..a5aedc58856 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.cc @@ -17,12 +17,12 @@ #include "BKE_paint.h" #include "BKE_pbvh.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "bmesh.h" -#include -#include +#include +#include void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], @@ -180,7 +180,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; Sculpt *sd = data->sd; const Brush *brush = data->brush; @@ -241,8 +241,8 @@ static void SCULPT_enhance_details_brush(Sculpt *sd, if (SCULPT_stroke_is_first_brush_step(ss->cache)) { const int totvert = SCULPT_vertex_count_get(ss); - ss->cache->detail_directions = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "details directions"); + ss->cache->detail_directions = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[3]), "details directions")); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -253,12 +253,11 @@ static void SCULPT_enhance_details_brush(Sculpt *sd, } } - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -269,7 +268,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; Sculpt *sd = data->sd; const Brush *brush = data->brush; @@ -345,7 +344,7 @@ void SCULPT_smooth(Sculpt *sd, CLAMP(bstrength, 0.0f, 1.0f); - count = (int)(bstrength * max_iterations); + count = int(bstrength * max_iterations); last = max_iterations * (bstrength - count * fract); if (type == PBVH_FACES && !ss->pmap) { @@ -359,14 +358,13 @@ void SCULPT_smooth(Sculpt *sd, for (iteration = 0; iteration <= count; iteration++) { const float strength = (iteration != count) ? 1.0f : last; - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .smooth_mask = smooth_mask, - .strength = strength, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.smooth_mask = smooth_mask; + data.strength = strength; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -447,7 +445,7 @@ void SCULPT_surface_smooth_displace_step(SculptSession *ss, static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = ss->cache->bstrength; @@ -499,7 +497,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; const float bstrength = ss->cache->bstrength; @@ -543,12 +541,11 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in Brush *brush = BKE_paint_brush(&sd->paint); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.cc similarity index 92% rename from source/blender/editors/sculpt_paint/sculpt_transform.c rename to source/blender/editors/sculpt_paint/sculpt_transform.cc index b8ee3404159..9b487675c88 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.c +++ b/source/blender/editors/sculpt_paint/sculpt_transform.cc @@ -27,20 +27,17 @@ #include "ED_sculpt.h" #include "ED_view3d.h" #include "paint_intern.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" #include "RNA_access.h" #include "RNA_define.h" #include "bmesh.h" -#include -#include +#include +#include -void ED_sculpt_init_transform(struct bContext *C, - Object *ob, - const int mval[2], - const char *undo_name) +void ED_sculpt_init_transform(bContext *C, Object *ob, const int mval[2], const char *undo_name) { Sculpt *sd = CTX_data_tool_settings(C)->sculpt; SculptSession *ss = ob->sculpt; @@ -72,7 +69,7 @@ void ED_sculpt_init_transform(struct bContext *C, } static void sculpt_transform_matrices_init(SculptSession *ss, - const char symm, + const ePaintSymmetryFlags symm, const SculptTransformDisplacementMode t_mode, float r_transform_mats[8][4][4]) { @@ -96,7 +93,7 @@ static void sculpt_transform_matrices_init(SculptSession *ss, } for (int i = 0; i < PAINT_SYMM_AREAS; i++) { - ePaintSymmetryAreas v_symm = i; + ePaintSymmetryAreas v_symm = ePaintSymmetryAreas(i); copy_v3_v3(final_pivot_pos, ss->pivot_pos); @@ -137,10 +134,10 @@ static void sculpt_transform_matrices_init(SculptSession *ss, static void sculpt_transform_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; @@ -168,7 +165,7 @@ static void sculpt_transform_task_cb(void *__restrict userdata, } copy_v3_v3(transformed_co, start_co); - mul_m4_v3(data->transform_mats[(int)symm_area], transformed_co); + mul_m4_v3(data->transform_mats[int(symm_area)], transformed_co); sub_v3_v3v3(disp, transformed_co, start_co); mul_v3_fl(disp, 1.0f - fade); add_v3_v3v3(vd.co, start_co, disp); @@ -185,13 +182,12 @@ static void sculpt_transform_task_cb(void *__restrict userdata, static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob) { SculptSession *ss = ob->sculpt; - const char symm = SCULPT_mesh_symmetry_xyz_get(ob); + const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(ob); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; sculpt_transform_matrices_init( ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats); @@ -206,10 +202,10 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob) static void sculpt_elastic_transform_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; @@ -262,14 +258,13 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float BLI_assert(ss->filter_cache->transform_displacement_mode == SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL); - const char symm = SCULPT_mesh_symmetry_xyz_get(ob); + const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(ob); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = ss->filter_cache->nodes, - .elastic_transform_radius = transform_radius, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = ss->filter_cache->nodes; + data.elastic_transform_radius = transform_radius; sculpt_transform_matrices_init( ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats); @@ -279,7 +274,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float /* Elastic transform needs to apply all transform matrices to all vertices and then combine the * displacement proxies as all vertices are modified by all symmetry passes. */ - for (ePaintSymmetryFlags symmpass = 0; symmpass <= symm; symmpass++) { + for (ePaintSymmetryFlags symmpass = PAINT_SYMM_NONE; symmpass <= symm; symmpass++) { if (SCULPT_is_symmetry_iteration_valid(symmpass, symm)) { flip_v3_v3(data.elastic_transform_pivot, ss->pivot_pos, symmpass); flip_v3_v3(data.elastic_transform_pivot_init, ss->init_pivot_pos, symmpass); @@ -293,7 +288,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float SCULPT_combine_transform_proxies(sd, ob); } -void ED_sculpt_update_modal_transform(struct bContext *C, Object *ob) +void ED_sculpt_update_modal_transform(bContext *C, Object *ob) { Sculpt *sd = CTX_data_tool_settings(C)->sculpt; SculptSession *ss = ob->sculpt; @@ -340,7 +335,7 @@ void ED_sculpt_update_modal_transform(struct bContext *C, Object *ob) SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS); } -void ED_sculpt_end_transform(struct bContext *C, Object *ob) +void ED_sculpt_end_transform(bContext *C, Object *ob) { SculptSession *ss = ob->sculpt; if (ss->filter_cache) { @@ -349,13 +344,13 @@ void ED_sculpt_end_transform(struct bContext *C, Object *ob) SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS); } -typedef enum eSculptPivotPositionModes { +enum eSculptPivotPositionModes { SCULPT_PIVOT_POSITION_ORIGIN = 0, SCULPT_PIVOT_POSITION_UNMASKED = 1, SCULPT_PIVOT_POSITION_MASK_BORDER = 2, SCULPT_PIVOT_POSITION_ACTIVE_VERTEX = 3, SCULPT_PIVOT_POSITION_CURSOR_SURFACE = 4, -} eSculptPivotPositionModes; +}; static EnumPropertyItem prop_sculpt_pivot_position_types[] = { {SCULPT_PIVOT_POSITION_ORIGIN, @@ -383,7 +378,7 @@ static EnumPropertyItem prop_sculpt_pivot_position_types[] = { 0, "Surface", "Sets the pivot position to the surface under the cursor"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) @@ -420,7 +415,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) else { PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); float avg[3]; int total = 0; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index 302ec4a2005..ed52ee55312 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -79,7 +79,7 @@ #include "ED_undo.h" #include "bmesh.h" -#include "sculpt_intern.h" +#include "sculpt_intern.hh" /* Uncomment to print the undo stack in the console on push/undo/redo. */ //#define SCULPT_UNDO_DEBUG @@ -1839,7 +1839,7 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr CustomDataLayer *layer; layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain); - /* Temporary fix for T97408. This is a fundamental + /* Temporary fix for #97408. This is a fundamental * bug in the undo stack; the operator code needs to push * an extra undo step before running an operator if a * non-memfile undo system is active. diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 998fe50b9ac..cd1c7e31d43 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -685,7 +685,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm /* Winding was added to island detection in 5197aa04c6bd * However the sculpt tools can flip faces, potentially creating orphaned islands. - * See T100132 */ + * See #100132 */ const bool use_winding = false; const bool use_seams = true; data->elementMap = BM_uv_element_map_create( diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 08b795db0c3..e95ba993115 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -500,7 +500,7 @@ static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); - return !(STR_ELEM(prop_id, "filepath", "directory", "filename")); + return !STR_ELEM(prop_id, "filepath", "directory", "filename"); } static void sound_mixdown_draw(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c index 79047b171ef..bb8456f6486 100644 --- a/source/blender/editors/space_action/action_data.c +++ b/source/blender/editors/space_action/action_data.c @@ -586,7 +586,7 @@ void ED_animedit_unlink_action( if (strip->act == act) { /* Remove this strip, and the track too if it doesn't have anything else */ - BKE_nlastrip_free(&nlt->strips, strip, true); + BKE_nlastrip_remove_and_free(&nlt->strips, strip, true); if (nlt->strips.first == NULL) { BLI_assert(nstrip == NULL); diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index de3d306a0be..5e740f897fc 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -60,19 +60,20 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - int height = ACHANNEL_TOT_HEIGHT(ac, items); + const int height = ANIM_UI_get_channels_total_height(v2d, items); v2d->tot.ymin = -height; /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */ UI_view2d_sync(NULL, ac->area, v2d, V2D_LOCK_COPY); + const float channel_step = ANIM_UI_get_channel_step(); /* Loop through channels, and set up drawing depending on their type. */ { /* first pass: just the standard GL-drawing for backdrop + text */ size_t channel_index = 0; - float ymax = ACHANNEL_FIRST_TOP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { - float ymin = ymax - ACHANNEL_HEIGHT(ac); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step, channel_index++) { + const float ymin = ymax - ANIM_UI_get_channel_height(); /* check if visible */ if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || @@ -85,10 +86,10 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) { /* second pass: widgets */ uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); size_t channel_index = 0; - float ymax = ACHANNEL_FIRST_TOP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { - float ymin = ymax - ACHANNEL_HEIGHT(ac); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step, channel_index++) { + const float ymin = ymax - ANIM_UI_get_channel_height(); /* check if visible */ if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || @@ -115,7 +116,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) #define EXTRA_SCROLL_PAD 100.0f /* Draw manually set intended playback frame ranges for actions. */ -static void draw_channel_action_ranges(bAnimContext *ac, ListBase *anim_data, View2D *v2d) +static void draw_channel_action_ranges(ListBase *anim_data, View2D *v2d) { /* Variables for coalescing the Y region of one action. */ bAction *cur_action = NULL; @@ -123,8 +124,8 @@ static void draw_channel_action_ranges(bAnimContext *ac, ListBase *anim_data, Vi float cur_ymax; /* Walk through channels, grouping contiguous spans referencing the same action. */ - float ymax = ACHANNEL_FIRST_TOP(ac) + ACHANNEL_SKIP / 2; - float ystep = ACHANNEL_STEP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d) + ANIM_UI_get_channel_skip() / 2; + const float ystep = ANIM_UI_get_channel_step(); float ymin = ymax - ystep; for (bAnimListElem *ale = anim_data->first; ale; ale = ale->next, ymax = ymin, ymin -= ystep) { @@ -193,13 +194,13 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - int height = ACHANNEL_TOT_HEIGHT(ac, items); + const int height = ANIM_UI_get_channels_total_height(v2d, items); v2d->tot.ymin = -height; /* Draw the manual frame ranges for actions in the background of the dopesheet. * The action editor has already drawn the range for its action so it's not needed. */ if (ac->datatype == ANIMCONT_DOPESHEET) { - draw_channel_action_ranges(ac, &anim_data, v2d); + draw_channel_action_ranges(&anim_data, v2d); } /* Draw the background strips. */ @@ -211,10 +212,10 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region GPU_blend(GPU_BLEND_ALPHA); /* first backdrop strips */ - float ymax = ACHANNEL_FIRST_TOP(ac); - - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { - float ymin = ymax - ACHANNEL_HEIGHT(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); + const float channel_step = ANIM_UI_get_channel_step(); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step) { + const float ymin = ymax - ANIM_UI_get_channel_height(); /* check if visible */ if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || @@ -366,12 +367,14 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region action_flag &= ~(SACTION_SHOW_INTERPOLATION | SACTION_SHOW_EXTREMES); } - ymax = ACHANNEL_FIRST_TOP(ac); + ymax = ANIM_UI_get_first_channel_top(v2d); struct AnimKeylistDrawList *draw_list = ED_keylist_draw_list_create(); - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { - float ymin = ymax - ACHANNEL_HEIGHT(ac); + const float scale_factor = ANIM_UI_get_keyframe_scale_factor(); + + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step) { + const float ymin = ymax - ANIM_UI_get_channel_height(); float ycenter = (ymin + ymax) / 2.0f; /* check if visible */ @@ -384,32 +387,28 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region /* draw 'keyframes' for each specific datatype */ switch (ale->datatype) { case ALE_ALL: - draw_summary_channel(draw_list, ale->data, ycenter, ac->yscale_fac, action_flag); + draw_summary_channel(draw_list, ale->data, ycenter, scale_factor, action_flag); break; case ALE_SCE: - draw_scene_channel( - draw_list, ads, ale->key_data, ycenter, ac->yscale_fac, action_flag); + draw_scene_channel(draw_list, ads, ale->key_data, ycenter, scale_factor, action_flag); break; case ALE_OB: - draw_object_channel( - draw_list, ads, ale->key_data, ycenter, ac->yscale_fac, action_flag); + draw_object_channel(draw_list, ads, ale->key_data, ycenter, scale_factor, action_flag); break; case ALE_ACT: - draw_action_channel( - draw_list, adt, ale->key_data, ycenter, ac->yscale_fac, action_flag); + draw_action_channel(draw_list, adt, ale->key_data, ycenter, scale_factor, action_flag); break; case ALE_GROUP: - draw_agroup_channel(draw_list, adt, ale->data, ycenter, ac->yscale_fac, action_flag); + draw_agroup_channel(draw_list, adt, ale->data, ycenter, scale_factor, action_flag); break; case ALE_FCURVE: - draw_fcurve_channel( - draw_list, adt, ale->key_data, ycenter, ac->yscale_fac, action_flag); + draw_fcurve_channel(draw_list, adt, ale->key_data, ycenter, scale_factor, action_flag); break; case ALE_GPFRAME: - draw_gpl_channel(draw_list, ads, ale->data, ycenter, ac->yscale_fac, action_flag); + draw_gpl_channel(draw_list, ads, ale->data, ycenter, scale_factor, action_flag); break; case ALE_MASKLAY: - draw_masklay_channel(draw_list, ads, ale->data, ycenter, ac->yscale_fac, action_flag); + draw_masklay_channel(draw_list, ads, ale->data, ycenter, scale_factor, action_flag); break; } } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 4c1a86a88e3..094eccf4114 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -315,16 +315,16 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *r_min ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through all channels, finding the first one that's selected */ - float ymax = ACHANNEL_FIRST_TOP(ac); - - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { + float ymax = ANIM_UI_get_first_channel_top(&ac->region->v2d); + const float channel_step = ANIM_UI_get_channel_step(); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step) { const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); /* must be selected... */ if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) && ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT)) { /* update best estimate */ - *r_min = ymax - ACHANNEL_HEIGHT(ac); + *r_min = ymax - ANIM_UI_get_channel_height(); *r_max = ymax; /* is this high enough priority yet? */ @@ -524,7 +524,7 @@ static eKeyPasteError paste_action_keys(bAnimContext *ac, * - First time we try to filter more strictly, allowing only selected channels * to allow copying animation between channels * - Second time, we loosen things up if nothing was found the first time, allowing - * users to just paste keyframes back into the original curve again T31670. + * users to just paste keyframes back into the original curve again #31670. */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index a425026a1ef..0c416712a0e 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -61,8 +61,14 @@ static bAnimListElem *actkeys_find_list_element_at_position(bAnimContext *ac, float view_x, view_y; int channel_index; UI_view2d_region_to_view(v2d, region_x, region_y, &view_x, &view_y); - UI_view2d_listview_view_to_cell( - 0, ACHANNEL_STEP(ac), 0, ACHANNEL_FIRST_TOP(ac), view_x, view_y, NULL, &channel_index); + UI_view2d_listview_view_to_cell(0, + ANIM_UI_get_channel_step(), + 0, + ANIM_UI_get_first_channel_top(v2d), + view_x, + view_y, + NULL, + &channel_index); ListBase anim_data = {NULL, NULL}; ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -152,7 +158,7 @@ static void actkeys_find_key_in_list_element(bAnimContext *ac, AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* standard channel height (to allow for some slop) */ - float key_hsize = ACHANNEL_HEIGHT(ac) * 0.8f; + float key_hsize = ANIM_UI_get_channel_height() * 0.8f; /* half-size (for either side), but rounded up to nearest int (for easier targeting) */ key_hsize = roundf(key_hsize / 2.0f); @@ -462,14 +468,15 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho /* init editing data */ memset(&sel_data.ked, 0, sizeof(KeyframeEditData)); - float ymax = ACHANNEL_FIRST_TOP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); + const float channel_step = ANIM_UI_get_channel_step(); /* loop over data, doing box select */ - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* get new vertical minimum extent of channel */ - float ymin = ymax - ACHANNEL_STEP(ac); + float ymin = ymax - channel_step; /* set horizontal range (if applicable) */ if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) { @@ -713,14 +720,15 @@ static void region_select_action_keys( sel_data.ked.data = &scaled_rectf; } - float ymax = ACHANNEL_FIRST_TOP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); + const float channel_step = ANIM_UI_get_channel_step(); /* loop over data, doing region select */ - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* get new vertical minimum extent of channel */ - float ymin = ymax - ACHANNEL_STEP(ac); + const float ymin = ymax - channel_step; /* compute midpoint of channel (used for testing if the key is in the region or not) */ sel_data.ked.channel_y = (ymin + ymax) / 2.0f; @@ -919,7 +927,7 @@ static const EnumPropertyItem prop_column_select_types[] = { /* ------------------- */ /* Selects all visible keyframes between the specified markers */ -/* TODO(@campbellbarton): this is almost an _exact_ duplicate of a function of the same name in +/* TODO(@ideasman42): this is almost an _exact_ duplicate of a function of the same name in * graph_select.c should de-duplicate. */ static void markers_selectkeys_between(bAnimContext *ac) { @@ -1776,7 +1784,7 @@ static int mouse_action_keys(bAnimContext *ac, /* apply selection to keyframes */ if (column) { /* select all keyframes in the same frame as the one we hit on the active channel - * [T41077]: "frame" not "selx" here (i.e. no NLA corrections yet) as the code here + * [#41077]: "frame" not "selx" here (i.e. no NLA corrections yet) as the code here * does that itself again as it needs to work on multiple data-blocks. */ actkeys_mselect_column(ac, select_mode, frame); diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 2f22121f7de..5a7be3be4a5 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -534,7 +534,7 @@ static void action_listener(const wmSpaceTypeListenerParams *params) } /* for simple edits to the curve data though (or just plain selections), * a simple redraw should work - * (see T39851 for an example of how this can go wrong) + * (see #39851 for an example of how this can go wrong) */ else { ED_area_tag_redraw(area); @@ -637,7 +637,7 @@ static void action_listener(const wmSpaceTypeListenerParams *params) break; case NC_WINDOW: if (saction->runtime.flag & SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC) { - /* force redraw/refresh after undo/redo, see: T28962. */ + /* force redraw/refresh after undo/redo, see: #28962. */ ED_area_tag_refresh(area); } break; @@ -781,7 +781,7 @@ static void action_refresh(const bContext *C, ScrArea *area) /* Tag everything for redraw * - Regions (such as header) need to be manually tagged for redraw too - * or else they don't update T28962. + * or else they don't update #28962. */ ED_area_tag_redraw(area); for (region = area->regionbase.first; region; region = region->next) { diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index c5f457b3fd8..463e1a14954 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -965,7 +965,7 @@ int /*eContextResult*/ buttons_context(const bContext *C, Object *ob = ptr->data; if (ob && OB_TYPE_SUPPORT_MATERIAL(ob->type) && ob->totcol) { - /* a valid actcol isn't ensured T27526. */ + /* a valid actcol isn't ensured #27526. */ int matnr = ob->actcol - 1; if (matnr < 0) { matnr = 0; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index b45abcf8068..6ccb8d6ca39 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -233,7 +233,7 @@ static int file_browse_exec(bContext *C, wmOperator *op) ED_undo_push(C, undostr); } - /* Special annoying exception, filesel on redo panel T26618. */ + /* Special annoying exception, filesel on redo panel #26618. */ { wmOperator *redo_op = WM_operator_last_redo(C); if (redo_op) { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 5ebc41d9cc7..b9abcfaa6f5 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -232,7 +232,7 @@ int ED_space_clip_get_clip_frame_number(const SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); - /* Caller must ensure space does have a valid clip, otherwise it will crash, see T45017. */ + /* Caller must ensure space does have a valid clip, otherwise it will crash, see #45017. */ return BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index d94228a2dad..3a2cbfdfad3 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -897,7 +897,7 @@ static void clip_main_region_draw(const bContext *C, ARegion *region) /* callback */ /* TODO(sergey): For being consistent with space image the projection needs to be configured * the way how the commented out code does it. This works correct for tracking data, but it - * causes wrong aspect correction for mask editor (see T84990). */ + * causes wrong aspect correction for mask editor (see #84990). */ // GPU_matrix_push_projection(); // wmOrtho2(region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin, // region->v2d.cur.ymax); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index e9a7080ff35..8616707e42e 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1403,7 +1403,7 @@ int file_highlight_set(SpaceFile *sfile, ARegion *region, int mx, int my) params = ED_fileselect_get_active_params(sfile); /* In case #SpaceFile.browse_mode just changed, the area may be pending a refresh still, which is - * what creates the params for the current browse mode. See T93508. */ + * what creates the params for the current browse mode. See #93508. */ if (!params) { return false; } @@ -2203,7 +2203,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w int deltay = 0; /* We adjust speed of scrolling to avoid tens of seconds of it in e.g. directories with tens of - * thousands of folders... See T65782. */ + * thousands of folders... See #65782. */ /* This will slow down scrolling when approaching final goal, also avoids going too far and * having to bounce back... */ @@ -2485,7 +2485,7 @@ static void file_expand_directory(bContext *C) { BLI_windows_get_default_root_dir(params->dir); } - /* change "C:" --> "C:\", T28102. */ + /* change "C:" --> "C:\", #28102. */ else if ((isalpha(params->dir[0]) && (params->dir[1] == ':')) && (params->dir[2] == '\0')) { params->dir[2] = '\\'; params->dir[3] = '\0'; diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 2c63c3460de..3a944f92308 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -185,7 +185,7 @@ struct FileListEntryPreview { }; /* Dummy wrapper around FileListEntryPreview to ensure we do not access freed memory when freeing - * tasks' data (see T74609). */ + * tasks' data (see #74609). */ struct FileListEntryPreviewTaskData { FileListEntryPreview *preview; }; @@ -633,7 +633,7 @@ static bool is_hidden_dot_filename(const char *filename, const FileListInternEnt while (sep) { /* This happens when a path contains 'ALTSEP', '\' on Unix for e.g. * Supporting alternate slashes in paths is a bigger task involving changes - * in many parts of the code, for now just prevent an assert, see T74579. */ + * in many parts of the code, for now just prevent an assert, see #74579. */ #if 0 BLI_assert(sep[1] != '\0'); #endif @@ -3587,7 +3587,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, /* ARRRG! We have to be very careful *not to use* common BLI_path_util helpers over * entry->relpath itself (nor any path containing it), since it may actually be a datablock - * name inside .blend file, which can have slashes and backslashes! See T46827. + * name inside .blend file, which can have slashes and backslashes! See #46827. * Note that in the end, this means we 'cache' valid relative subdir once here, * this is actually better. */ BLI_strncpy(rel_subdir, subdir, sizeof(rel_subdir)); @@ -4062,7 +4062,7 @@ void filelist_readjob_start(FileList *filelist, const int space_notifier, const /* The file list type may not support threading so execute immediately. Same when only rereading * #Main data (which we do quite often on changes to #Main, since it's the easiest and safest way * to ensure the displayed data is up to date), because some operations executing right after - * main data changed may need access to the ID files (see T93691). */ + * main data changed may need access to the ID files (see #93691). */ const bool no_threads = (filelist->tags & FILELIST_TAGS_NO_THREADS) || flrj->only_main_data; if (no_threads) { diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 12d05054e9b..e4f5b3e709c 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -85,7 +85,7 @@ static void fileselect_initialize_params_common(SpaceFile *sfile, FileSelectPara folder_history_list_ensure_for_active_browse_mode(sfile); folderlist_pushdir(sfile->folders_prev, params->dir); - /* Switching thumbnails needs to recalc layout T28809. */ + /* Switching thumbnails needs to recalc layout #28809. */ if (sfile->layout) { sfile->layout->dirty = true; } @@ -1144,7 +1144,7 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche */ for (int i = 0; i < n; i++) { FileDirEntry *file = filelist_file(sfile->files, i); - /* Do not check whether file is a file or dir here! Causes: T44243 + /* Do not check whether file is a file or dir here! Causes: #44243 * (we do accept directories at this stage). */ if (fnmatch(pattern, file->relpath, 0) == 0) { filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); @@ -1228,7 +1228,7 @@ int autocomplete_file(struct bContext *C, char *str, void * /*arg_v*/) void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile) { - /* Only null in rare cases, see: T29734. */ + /* Only null in rare cases, see: #29734. */ if (sfile->files) { filelist_readjob_stop(sfile->files, wm); filelist_freelib(sfile->files); diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 959f8b01ec8..0e46a2eafe3 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -332,7 +332,7 @@ void fsmenu_entry_refresh_valid(struct FSMenuEntry *fsentry) #ifdef WIN32 /* XXX Special case, always consider those as valid. * Thanks to Windows, which can spend five seconds to perform a mere stat() call on those paths - * See T43684. */ + * See #43684. */ const char *exceptions[] = {"A:\\", "B:\\", NULL}; const size_t exceptions_len[] = {strlen(exceptions[0]), strlen(exceptions[1]), 0}; int i; @@ -653,7 +653,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* Skip over floppy disks A & B. */ if (i > 1) { - /* Friendly volume descriptions without using SHGetFileInfoW (T85689). */ + /* Friendly volume descriptions without using SHGetFileInfoW (#85689). */ BLI_strncpy_wchar_from_utf8(wline, tmps, 4); IShellFolder *desktop; if (SHGetDesktopFolder(&desktop) == S_OK) { diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 8ada6d31a2d..4b51da66ac5 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -304,7 +304,7 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez /* update callback for editing coordinates of right handle in active keyframe properties * NOTE: we cannot just do graphedit_activekey_handles_cb() due to "order of computation" - * weirdness (see calchandleNurb_intern() and T39911) + * weirdness (see calchandleNurb_intern() and #39911) */ static void graphedit_activekey_left_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr) { @@ -528,7 +528,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel) /* next handle - only if current is Bezier interpolation */ if (bezt->ipo == BEZT_IPO_BEZ) { - /* NOTE: special update callbacks are needed on the coords here due to T39911 */ + /* NOTE: special update callbacks are needed on the coords here due to #39911 */ col = uiLayoutColumn(layout, true); uiItemL_respect_property_split(col, IFACE_("Right Handle Type"), ICON_NONE); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index a19cbb9b7fa..f315690a50d 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -606,7 +606,7 @@ static void draw_fcurve_curve(bAnimContext *ac, * * Although the "Beauty Draw" flag was originally for AA'd * line drawing, the sampling rate here has a much greater - * impact on performance (e.g. for T40372)! + * impact on performance (e.g. for #40372)! * * This one still amounts to 10 sample-frames for each 1-frame interval * which should be quite a decent approximation in many situations. @@ -616,7 +616,7 @@ static void draw_fcurve_curve(bAnimContext *ac, } } else { - /* "Higher Precision" but slower - especially on larger windows (e.g. T40372) */ + /* "Higher Precision" but slower - especially on larger windows (e.g. #40372) */ if (samplefreq < 0.00001f) { samplefreq = 0.00001f; } @@ -1398,16 +1398,17 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) /* Update max-extent of channels here (taking into account scrollers): * - this is done to allow the channel list to be scrollable, but must be done here * to avoid regenerating the list again and/or also because channels list is drawn first */ - height = ACHANNEL_TOT_HEIGHT(ac, items); + height = ANIM_UI_get_channels_total_height(v2d, items); v2d->tot.ymin = -height; + const float channel_step = ANIM_UI_get_channel_step(); /* Loop through channels, and set up drawing depending on their type. */ { /* first pass: just the standard GL-drawing for backdrop + text */ size_t channel_index = 0; - float ymax = ACHANNEL_FIRST_TOP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { - float ymin = ymax - ACHANNEL_HEIGHT(ac); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step, channel_index++) { + const float ymin = ymax - ANIM_UI_get_channel_height(); /* check if visible */ if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || @@ -1420,13 +1421,13 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) { /* second pass: widgets */ uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); size_t channel_index = 0; - float ymax = ACHANNEL_FIRST_TOP(ac); + float ymax = ANIM_UI_get_first_channel_top(v2d); /* set blending again, as may not be set in previous step */ GPU_blend(GPU_BLEND_ALPHA); - for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { - float ymin = ymax - ACHANNEL_HEIGHT(ac); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= channel_step, channel_index++) { + const float ymin = ymax - ANIM_UI_get_channel_height(); /* check if visible */ if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 1ad68eef2f5..34c34613cf6 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -485,7 +485,7 @@ static eKeyPasteError paste_graph_keys(bAnimContext *ac, * - First time we try to filter more strictly, allowing only selected channels * to allow copying animation between channels * - Second time, we loosen things up if nothing was found the first time, allowing - * users to just paste keyframes back into the original curve again T31670. + * users to just paste keyframes back into the original curve again #31670. */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index dec360892ec..f92fe71455b 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -1134,7 +1134,7 @@ static const EnumPropertyItem prop_column_select_types[] = { /* ------------------- */ /* Selects all visible keyframes between the specified markers */ -/* TODO(@campbellbarton): this is almost an _exact_ duplicate of a function of the same name in +/* TODO(@ideasman42): this is almost an _exact_ duplicate of a function of the same name in * action_select.c should de-duplicate. */ static void markers_selectkeys_between(bAnimContext *ac) { @@ -1809,7 +1809,7 @@ static int mouse_graph_keys(bAnimContext *ac, /* Set active F-Curve when something was actually selected (so not on a deselect), except when * dragging the selected keys. Needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY), - * otherwise the active flag won't be set T26452. */ + * otherwise the active flag won't be set #26452. */ if (!run_modal && (nvi->fcu->flag & FCURVE_SELECTED) && something_was_selected) { /* NOTE: Sync the filter flags with findnearest_fcurve_vert. */ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 1dc02fee59d..de96cad8de6 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -149,7 +149,7 @@ static void graph_init(struct wmWindowManager *wm, ScrArea *area) /* force immediate init of any invalid F-Curve colors */ /* XXX: but, don't do SIPO_TEMP_NEEDCHANSYNC (i.e. channel select state sync) * as this is run on each region resize; setting this here will cause selection - * state to be lost on area/region resizing. T35744. + * state to be lost on area/region resizing. #35744. */ ED_area_tag_refresh(area); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index f6d21633bb3..13d3681b10e 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2601,7 +2601,7 @@ static int image_new_exec(bContext *C, wmOperator *op) } else { /* #BKE_image_add_generated creates one user by default, remove it if image is not linked to - * anything. ref. T94599. */ + * anything. ref. #94599. */ id_us_min(&ima->id); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index fd8c161687e..be899d42323 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -407,7 +407,7 @@ static void image_listener(const wmSpaceTypeListenerParams *params) Object *ob = BKE_view_layer_active_object_get(view_layer); /* \note With a geometry nodes modifier, the UVs on `ob` can change in response to * any change on `wmn->reference`. If we could track the upstream dependencies, - * unnecessary redraws could be reduced. Until then, just redraw. See T98594. */ + * unnecessary redraws could be reduced. Until then, just redraw. See #98594. */ if (ob && (ob->mode & OB_MODE_EDIT)) { if (sima->lock && (sima->flag & SI_DRAWSHADOW)) { ED_area_tag_refresh(area); diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 3c0238806bf..a783ee32779 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -145,7 +145,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, int channel_index, } } - /* change active object - regardless of whether it is now selected [T37883] */ + /* change active object - regardless of whether it is now selected [#37883] */ ED_object_base_activate_with_mode_exit_if_needed(C, base); /* adds notifier */ if ((adt) && (adt->flag & ADT_UI_SELECTED)) { diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 8a3c6745259..b61b5d8e63b 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1305,15 +1305,15 @@ static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op)) if (strip->flag & NLASTRIP_FLAG_SELECT) { /* if a strip either side of this was a transition, delete those too */ if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION)) { - BKE_nlastrip_free(&nlt->strips, strip->prev, true); + BKE_nlastrip_remove_and_free(&nlt->strips, strip->prev, true); } if ((nstrip) && (nstrip->type == NLASTRIP_TYPE_TRANSITION)) { nstrip = nstrip->next; - BKE_nlastrip_free(&nlt->strips, strip->next, true); + BKE_nlastrip_remove_and_free(&nlt->strips, strip->next, true); } /* finally, delete this strip */ - BKE_nlastrip_free(&nlt->strips, strip, true); + BKE_nlastrip_remove_and_free(&nlt->strips, strip, true); } } } @@ -1824,7 +1824,7 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op)) if (BKE_nlatrack_has_space(nltn, strip->start, strip->end)) { /* remove from its current track, and add to the one above * (it 'should' work, so no need to worry) */ - BLI_remlink(&nlt->strips, strip); + BKE_nlatrack_remove_strip(nlt, strip); BKE_nlatrack_add_strip(nltn, strip, is_liboverride); } } @@ -1916,7 +1916,7 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op)) if (BKE_nlatrack_has_space(nltp, strip->start, strip->end)) { /* remove from its current track, and add to the one above * (it 'should' work, so no need to worry) */ - BLI_remlink(&nlt->strips, strip); + BKE_nlatrack_remove_strip(nlt, strip); BKE_nlatrack_add_strip(nltp, strip, is_liboverride); } } diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 34b5ba3ab22..efe3adb2fa5 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1456,6 +1456,7 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P case SOCK_STRING: case SOCK_OBJECT: case SOCK_COLLECTION: + case SOCK_IMAGE: case SOCK_TEXTURE: case SOCK_MATERIAL: { uiItemR(col, ptr, "default_value", DEFAULT_FLAGS, IFACE_("Default"), 0); @@ -1463,7 +1464,13 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P } } - uiItemR(layout, ptr, "hide_value", DEFAULT_FLAGS, nullptr, 0); + col = uiLayoutColumn(layout, false); + uiItemR(col, ptr, "hide_value", DEFAULT_FLAGS, nullptr, 0); + + const bNodeTree *node_tree = reinterpret_cast(ptr->owner_id); + if (sock->in_out == SOCK_IN && node_tree->type == NTREE_GEOMETRY) { + uiItemR(col, ptr, "hide_in_modifier", DEFAULT_FLAGS, nullptr, 0); + } } static void node_socket_virtual_draw_color(bContext * /*C*/, diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 53a86e23ce1..31dc2695c97 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -51,6 +51,7 @@ #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" +#include "GPU_shader_shared.h" #include "GPU_state.h" #include "GPU_viewport.h" diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index fc039746639..54dc0772c96 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -329,7 +329,7 @@ void ED_node_composite_job(const bContext *C, bNodeTree *nodetree, Scene *scene_ Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - /* See T32272. */ + /* See #32272. */ if (G.is_rendering) { return; } @@ -715,7 +715,7 @@ void ED_node_set_active( if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { /* If active texture changed, free glsl materials. */ LISTBASE_FOREACH (Material *, ma, &bmain->materials) { - if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) { + if (ma->nodetree && ma->use_nodes && ntreeContainsTree(ma->nodetree, ntree)) { GPU_material_free(&ma->gpumaterial); /* Sync to active texpaint slot, otherwise we can end up painting on a different slot @@ -734,7 +734,7 @@ void ED_node_set_active( } LISTBASE_FOREACH (World *, wo, &bmain->worlds) { - if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) { + if (wo->nodetree && wo->use_nodes && ntreeContainsTree(wo->nodetree, ntree)) { GPU_material_free(&wo->gpumaterial); } } diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index ca0361e82dc..6f5225c0491 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -235,7 +235,7 @@ static bool node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode) * This also removes remaining links to and from interface nodes. */ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { - /* We must delay removal since sockets will reference this node. see: T52092 */ + /* We must delay removal since sockets will reference this node. see: #52092 */ nodes_delayed_free.append(node); } @@ -1094,24 +1094,6 @@ void NODE_OT_group_make(wmOperatorType *ot) /** \name Group Insert Operator * \{ */ -static bool node_tree_contains_tree_recursive(const bNodeTree &ntree_to_search_in, - const bNodeTree &ntree_to_search_for) -{ - if (&ntree_to_search_in == &ntree_to_search_for) { - return true; - } - ntree_to_search_in.ensure_topology_cache(); - for (const bNode *node : ntree_to_search_in.group_nodes()) { - if (node->id) { - if (node_tree_contains_tree_recursive(*reinterpret_cast(node->id), - ntree_to_search_for)) { - return true; - } - } - } - return false; -} - static int node_group_insert_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); @@ -1133,7 +1115,7 @@ static int node_group_insert_exec(bContext *C, wmOperator *op) if (!group->is_group() || group->id == nullptr) { continue; } - if (node_tree_contains_tree_recursive(*reinterpret_cast(group->id), *ngroup)) { + if (ntreeContainsTree(reinterpret_cast(group->id), ngroup)) { BKE_reportf( op->reports, RPT_WARNING, "Can not insert group '%s' in '%s'", group->name, gnode->name); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 30a4b950e60..73cc64bbf61 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -353,7 +353,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const bNode *node_fr = sorted_nodes[i]; bNode *node_to = sorted_nodes[i + 1]; - /* Corner case: input/output node aligned the wrong way around (T47729). */ + /* Corner case: input/output node aligned the wrong way around (#47729). */ if (BLI_listbase_is_empty(&node_to->inputs) || BLI_listbase_is_empty(&node_fr->outputs)) { std::swap(node_fr, node_to); } @@ -538,6 +538,11 @@ static bNodeSocket *determine_socket_to_view(bNode &node_to_view) /* This socket is linked to a deactivated viewer, the viewer should be activated. */ return socket; } + if (socket->type == SOCK_GEOMETRY && (target_node.flag & NODE_DO_OUTPUT)) { + /* Skip geometry sockets connected to viewer nodes when deciding whether to cycle through + * outputs. */ + continue; + } last_linked_socket_index = socket->index(); } } diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index fbd625932dd..0fd6c6b72cb 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -55,7 +55,7 @@ static bool is_event_over_node_or_socket(const bContext &C, const wmEvent &event /** * Function to detect if there is a visible view3d that uses workbench in texture mode. - * This function is for fixing T76970 for Blender 2.83. The actual fix should add a mechanism in + * This function is for fixing #76970 for Blender 2.83. The actual fix should add a mechanism in * the depsgraph that can be used by the draw engines to check if they need to be redrawn. * * We don't want to add these risky changes this close before releasing 2.83 without good testing diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc index f64b44b00dc..ce37057bcf3 100644 --- a/source/blender/editors/space_node/node_view.cc +++ b/source/blender/editors/space_node/node_view.cc @@ -645,7 +645,7 @@ static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event) ImageSampleInfo *info; /* Don't handle events intended for nodes (which rely on click/drag distinction). - * which this operator would use since sampling is normally activated on press, see: T98191. */ + * which this operator would use since sampling is normally activated on press, see: #98191. */ if (node_or_socket_isect_event(*C, *event)) { return OPERATOR_PASS_THROUGH; } diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index def49ad883b..df8da8a68c0 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -71,7 +71,7 @@ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from) if (ntree->type != NTREE_GEOMETRY) { /* This can probably be removed for all node tree types. It mainly exists because it was not - * possible to store id references in custom properties. Also see T36024. I don't want to + * possible to store id references in custom properties. Also see #36024. I don't want to * remove it for all tree types in bcon3 though. */ id_us_ensure_real(&ntree->id); } diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc index 20319a8befe..c2975833dcc 100644 --- a/source/blender/editors/space_outliner/outliner_select.cc +++ b/source/blender/editors/space_outliner/outliner_select.cc @@ -363,7 +363,7 @@ static void tree_element_object_activate(bContext *C, /* Only in object mode so we can switch the active object, * keeping all objects in the current 'mode' selected, useful for multi-pose/edit mode. * This keeps the convention that all objects in the current mode are also selected. - * see T55246. */ + * see #55246. */ if ((scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ? (ob->mode == OB_MODE_OBJECT) : true) { @@ -416,7 +416,7 @@ static void tree_element_material_activate(bContext *C, } /* Tagging object for update seems a bit stupid here, but looks like we have to do it - * for render views to update. See T42973. + * for render views to update. See #42973. * Note that RNA material update does it too, see e.g. rna_MaterialSlot_update(). */ DEG_id_tag_update((ID *)ob, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, nullptr); @@ -1402,7 +1402,7 @@ static void do_outliner_item_activate_tree_element(bContext *C, TSE_EBONE, TSE_LAYER_COLLECTION)) { /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several - * objects, we do not want to switch out of edit mode (see T48328 for details). */ + * objects, we do not want to switch out of edit mode (see #48328 for details). */ } else if (do_activate_data) { tree_element_object_activate(C, diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index 1502b6915de..e1cc1a74c7a 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -1570,7 +1570,7 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner, te_next = te->next; if (outliner_element_visible_get(scene, view_layer, te, exclude_filter) == false) { /* Don't free the tree, but extract the children from the parent and add to this tree. */ - /* This also needs filtering the subtree prior (see T69246). */ + /* This also needs filtering the subtree prior (see #69246). */ outliner_filter_subtree( space_outliner, scene, view_layer, &te->subtree, search_string, exclude_filter); te_next = outliner_extract_children_from_subtree(te, lb); diff --git a/source/blender/editors/space_outliner/space_outliner.cc b/source/blender/editors/space_outliner/space_outliner.cc index af2da7fa872..d6b72c4eb7f 100644 --- a/source/blender/editors/space_outliner/space_outliner.cc +++ b/source/blender/editors/space_outliner/space_outliner.cc @@ -432,7 +432,7 @@ static void outliner_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRe if (unassigned) { /* Redraw is needed when removing data for multiple outlines show the same data. * without this, the stale data won't get fully flushed when this outliner - * is not the active outliner the user is interacting with. See T85976. */ + * is not the active outliner the user is interacting with. See #85976. */ ED_area_tag_redraw(area); } } diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index a32c8a3f85a..a8cdf2b6642 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -100,7 +100,7 @@ static int script_reload_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* TODO(@campbellbarton): this crashes on netrender and keying sets, need to look into why + /* TODO(@ideasman42): this crashes on netrender and keying sets, need to look into why * disable for now unless running in debug mode. */ /* It would be nice if we could detect when this is called from the Python @@ -108,7 +108,7 @@ static int script_reload_exec(bContext *C, wmOperator *op) if (true) { /* Postpone when called from Python so this can be called from an operator * that might be re-registered, crashing Blender when we try to read from the - * freed operator type which, see T80694. */ + * freed operator type which, see #80694. */ BPY_run_string_exec(C, (const char *[]){"bpy", NULL}, "def fn():\n" diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 5d74ca96613..a4c1a9b1139 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -769,7 +769,7 @@ static void draw_seq_outline(Scene *scene, immUniformColor3ubv(col); /* 2px wide outline for selected strips. */ - /* XXX: some platforms don't support OpenGL lines wider than 1px (see T57570), + /* XXX: some platforms don't support OpenGL lines wider than 1px (see #57570), * draw outline as four boxes instead. */ if (seq->flag & SELECT) { /* Left */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index c74997def2a..28d7f388ca5 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1220,7 +1220,7 @@ int seq_effect_find_selected(Scene *scene, *r_selseq2 = seq2; *r_selseq3 = seq3; - /* TODO(Richard): This function needs some refactoring, this is just quick hack for T73828. */ + /* TODO(Richard): This function needs some refactoring, this is just quick hack for #73828. */ if (SEQ_effect_get_num_inputs(type) < 3) { *r_selseq3 = NULL; } @@ -2492,17 +2492,22 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) /** \name Paste Operator * \{ */ -void ED_sequencer_deselect_all(Scene *scene) +bool ED_sequencer_deselect_all(Scene *scene) { Editing *ed = SEQ_editing_get(scene); + bool changed = false; if (ed == NULL) { - return; + return changed; } LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { - seq->flag &= ~SEQ_ALLSEL; + if (seq->flag & SEQ_ALLSEL) { + seq->flag &= ~SEQ_ALLSEL; + changed = true; + } } + return changed; } static void sequencer_paste_animation(bContext *C) @@ -2882,7 +2887,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "directory", directory); if (is_relative_path) { - /* TODO(@campbellbarton): shouldn't this already be relative from the filesel? + /* TODO(@ideasman42): shouldn't this already be relative from the filesel? * (as the 'filepath' is) for now just make relative here, * but look into changing after 2.60. */ BLI_path_rel(directory, BKE_main_blendfile_path(bmain)); diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c index a1dd9ce2ac2..762f2c178ab 100644 --- a/source/blender/editors/space_sequencer/sequencer_scopes.c +++ b/source/blender/editors/space_sequencer/sequencer_scopes.c @@ -17,7 +17,7 @@ #include "sequencer_intern.h" -/* XXX(@campbellbarton): why is this function better than BLI_math version? +/* XXX(@ideasman42): why is this function better than BLI_math version? * only difference is it does some normalize after, need to double check on this. */ static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3]) { diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 7f7e9878dd6..a8c0e2b5d22 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -974,8 +974,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) /* Deselect everything */ if (deselect_all || (seq && (extend == false && deselect == false && toggle == false))) { - ED_sequencer_deselect_all(scene); - changed = true; + changed |= ED_sequencer_deselect_all(scene); } /* Nothing to select, but strips could be deselected. */ diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index db4fc7da9dc..f6cf5bb771e 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -314,7 +314,7 @@ static int doc_scroll = 0; static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *event) { - /* NOTE(@campbellbarton): this code could be refactored or rewritten. */ + /* NOTE(@ideasman42): this code could be refactored or rewritten. */ SpaceText *st = CTX_wm_space_text(C); ScrArea *area = CTX_wm_area(C); ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); diff --git a/source/blender/editors/space_view3d/space_view3d.cc b/source/blender/editors/space_view3d/space_view3d.cc index 396e75f6b4e..25708ee7a67 100644 --- a/source/blender/editors/space_view3d/space_view3d.cc +++ b/source/blender/editors/space_view3d/space_view3d.cc @@ -37,6 +37,7 @@ #include "BKE_idprop.h" #include "BKE_lattice.h" #include "BKE_layer.h" +#include "BKE_lib_id.h" #include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_mball.h" @@ -702,6 +703,52 @@ static bool view3d_volume_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEven return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME); } +static bool view3d_geometry_nodes_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +{ + if (!view3d_drop_id_in_main_region_poll(C, drag, event, ID_NT)) { + return false; + } + + if (drag->type == WM_DRAG_ID) { + const bNodeTree *node_tree = reinterpret_cast( + WM_drag_get_local_ID(drag, ID_NT)); + if (!node_tree) { + return false; + } + return node_tree->type == NTREE_GEOMETRY; + } + + if (drag->type == WM_DRAG_ASSET) { + const wmDragAsset *asset_data = WM_drag_get_asset_data(drag, ID_NT); + if (!asset_data) { + return false; + } + const IDProperty *tree_type = BKE_asset_metadata_idprop_find(asset_data->metadata, "type"); + if (!tree_type || IDP_Int(tree_type) != NTREE_GEOMETRY) { + return false; + } + if (wmDropBox *drop_box = drag->drop_state.active_dropbox) { + const uint32_t uuid = RNA_int_get(drop_box->ptr, "session_uuid"); + const bNodeTree *node_tree = reinterpret_cast( + BKE_libblock_find_session_uuid(CTX_data_main(C), ID_NT, uuid)); + if (node_tree) { + return node_tree->type == NTREE_GEOMETRY; + } + } + } + return true; +} + +static char *view3d_geometry_nodes_drop_tooltip(bContext *C, + wmDrag * /*drag*/, + const int xy[2], + struct wmDropBox *drop) +{ + ARegion *region = CTX_wm_region(C); + int mval[2] = {xy[0] - region->winrct.xmin, xy[1] - region->winrct.ymin}; + return ED_object_ot_drop_geometry_nodes_tooltip(C, drop->ptr, mval); +} + static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state, Object *ob, float obmat_final[4][4]) @@ -746,7 +793,7 @@ static void view3d_ob_drop_copy_local_id(bContext * /*C*/, wmDrag *drag, wmDropB * make sharing code a bit difficult. */ static void view3d_ob_drop_copy_external_asset(bContext * /*C*/, wmDrag *drag, wmDropBox *drop) { - /* NOTE(@campbellbarton): Selection is handled here, de-selecting objects before append, + /* NOTE(@ideasman42): Selection is handled here, de-selecting objects before append, * using auto-select to ensure the new objects are selected. * This is done so #OBJECT_OT_transform_to_mouse (which runs after this drop handler) * can use the context setup here to place the objects. */ @@ -930,6 +977,12 @@ static void view3d_dropboxes() view3d_id_drop_copy, WM_drag_free_imported_drag_ID, view3d_mat_drop_tooltip); + WM_dropbox_add(lb, + "OBJECT_OT_drop_geometry_nodes", + view3d_geometry_nodes_drop_poll, + view3d_id_drop_copy, + WM_drag_free_imported_drag_ID, + view3d_geometry_nodes_drop_tooltip); WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, @@ -969,13 +1022,14 @@ static void view3d_widgets() WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_xform_gizmo_context); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_spot); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_point); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_area); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_target); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_force_field); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image); - /* TODO(@campbellbarton): Not working well enough, disable for now. */ + /* TODO(@ideasman42): Not working well enough, disable for now. */ #if 0 WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline); #endif @@ -1915,7 +1969,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes * it's simplest if all these methods behave consistently - respecting the object-mode * without showing the object. * - * See T85532 for alternatives that were considered. */ + * See #85532 for alternatives that were considered. */ const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); BKE_view_layer_synced_ensure(scene, view_layer); @@ -1992,7 +2046,7 @@ static void view3d_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRema view3d_id_remap_v3d(area, slink, view3d, mappings, false); view3d_id_remap_v3d_ob_centers(view3d, mappings); if (view3d->localvd != nullptr) { - /* Object centers in local-view aren't used, see: T52663 */ + /* Object centers in local-view aren't used, see: #52663 */ view3d_id_remap_v3d(area, slink, view3d->localvd, mappings, true); } BKE_viewer_path_id_remap(&view3d->viewer_path, mappings); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index f71ce54729c..380a0c47b3e 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -223,7 +223,7 @@ static float compute_scale_factor(const float ve_median, const float median) * Apply helpers. * \note In case we only have one element, * copy directly the value instead of applying the diff or scale factor. - * Avoids some glitches when going e.g. from 3 to 0.0001 (see T37327). + * Avoids some glitches when going e.g. from 3 to 0.0001 (see #37327). */ static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median) { @@ -1117,7 +1117,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (bezt->f2 & SELECT) { if (apply_vcos) { /* Here we always have to use the diff... :/ - * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see T37327), + * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see #37327), * unless we use doubles. */ add_v3_v3(bezt->vec[0], median->location); diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index 04559fb30dc..b50721a22c5 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -153,7 +153,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph, /* Calculate pixel-size factor once, this is used for lights and object-centers. */ { /* NOTE: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])' - * because of float point precision problems at large values T23908. */ + * because of float point precision problems at large values #23908. */ float v1[3], v2[3]; float len_px, len_sc; @@ -585,7 +585,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, alpha = ca->passepartalpha; } - immUniformColor4f(0.0f, 0.0f, 0.0f, alpha); + immUniformThemeColorAlpha(TH_CAMERA_PASSEPARTOUT, alpha); if (x1i > 0.0f) { immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f); @@ -1104,8 +1104,8 @@ static void draw_rotation_guide(const RegionView3D *rv3d) immUnbindProgram(); /* -- draw rotation center -- */ - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); - GPU_point_size(5.0f); + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + immUniform1f("size", 7.0f); immBegin(GPU_PRIM_POINTS, 1); immAttr4ubv(col, color); immVertex3fv(pos, o); @@ -1690,7 +1690,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph, { /* Free images which can have changed on frame-change. - * WARNING(@campbellbarton): can be slow so only free animated images. */ + * WARNING(@ideasman42): can be slow so only free animated images. */ BKE_image_free_anim_gputextures(G.main); } @@ -2266,7 +2266,7 @@ void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d) } } -/* NOTE: with NOUVEAU drivers the #glReadPixels() is very slow. T24339. */ +/* NOTE: with NOUVEAU drivers the #glReadPixels() is very slow. #24339. */ static ViewDepths *view3d_depths_create(ARegion *region) { ViewDepths *d = MEM_cnew("ViewDepths"); @@ -2412,7 +2412,7 @@ void ED_view3d_datamask(const Scene *scene, const View3D *v3d, CustomData_MeshMasks *r_cddata_masks) { - /* NOTE(@campbellbarton): as this function runs continuously while idle + /* NOTE(@ideasman42): as this function runs continuously while idle * (from #wm_event_do_depsgraph) take care to avoid expensive lookups. * While they won't hurt performance noticeably, they will increase CPU usage while idle. */ if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 23e06c895fc..d5b96e03f13 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -957,7 +957,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, /* As the tangent is arbitrary from the users point of view, * make the cursor 'roll' on the shortest angle. - * otherwise this can cause noticeable 'flipping', see T72419. */ + * otherwise this can cause noticeable 'flipping', see #72419. */ for (int axis = 0; axis < 2; axis++) { float tan_src[3] = {0, 0, 0}; tan_src[axis] = 1.0f; @@ -1032,7 +1032,7 @@ void ED_view3d_cursor3d_update(bContext *C, } else { /* Cursor may be outside of the view, - * prevent it getting 'lost', see: T40353 & T45301 */ + * prevent it getting 'lost', see: #40353 & #45301 */ zero_v2(rv3d->ofs_lock); } } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c index 8a4301d1314..308b6eca625 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c @@ -37,7 +37,7 @@ * \{ */ /* - * TODO(@campbellbarton): Current conversion is a approximation (usable not correct), + * TODO(@ideasman42): Current conversion is a approximation (usable not correct), * we'll need to take the next/previous bones into account to get the tangent directions. * First last matrices from 'BKE_pchan_bbone_spline_setup' are close but also not quite accurate * since they're not at either end-points on the curve. diff --git a/source/blender/editors/space_view3d/view3d_gizmo_light.c b/source/blender/editors/space_view3d/view3d_gizmo_light.c index d967b950bc5..f3db63b9a20 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_light.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_light.c @@ -42,6 +42,7 @@ typedef struct LightSpotWidgetGroup { wmGizmo *spot_angle; wmGizmo *spot_blend; + wmGizmo *spot_radius; } LightSpotWidgetGroup; static void gizmo_spot_blend_prop_matrix_get(const wmGizmo *UNUSED(gz), @@ -94,6 +95,48 @@ static void gizmo_spot_blend_prop_matrix_set(const wmGizmo *UNUSED(gz), RNA_property_update_main(CTX_data_main(C), scene, &light_ptr, spot_blend_prop); } +/* Used by spot light and point light. */ +static void gizmo_light_radius_prop_matrix_get(const wmGizmo *UNUSED(gz), + wmGizmoProperty *gz_prop, + void *value_p) +{ + BLI_assert(gz_prop->type->array_length == 16); + float(*matrix)[4] = value_p; + + const bContext *C = gz_prop->custom_func.user_data; + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer); + const Light *la = BKE_view_layer_active_object_get(view_layer)->data; + + /* Draw gizmo even when radius is zero. */ + const float diameter = fmaxf(2.0f * la->radius, 1e-2f); + matrix[0][0] = diameter; + matrix[1][1] = diameter; +} + +static void gizmo_light_radius_prop_matrix_set(const wmGizmo *UNUSED(gz), + wmGizmoProperty *gz_prop, + const void *value_p) +{ + const float(*matrix)[4] = value_p; + BLI_assert(gz_prop->type->array_length == 16); + + const bContext *C = gz_prop->custom_func.user_data; + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); + Light *la = BKE_view_layer_active_object_get(view_layer)->data; + + const float radius = 0.5f * len_v3(matrix[0]); + + PointerRNA light_ptr; + RNA_pointer_create(&la->id, &RNA_Light, la, &light_ptr); + PropertyRNA *radius_prop = RNA_struct_find_property(&light_ptr, "shadow_soft_size"); + RNA_property_float_set(&light_ptr, radius_prop, radius); + + RNA_property_update_main(CTX_data_main(C), scene, &light_ptr, radius_prop); +} + static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); @@ -154,6 +197,28 @@ static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgrou .user_data = (void *)C, }); } + + /* Spot radius gizmo. */ + { + ls_gzgroup->spot_radius = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); + wmGizmo *gz = ls_gzgroup->spot_radius; + RNA_enum_set(gz->ptr, + "transform", + ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_CIRCLE); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); + + WM_gizmo_target_property_def_func(gz, + "matrix", + &(const struct wmGizmoPropertyFnParams){ + .value_get_fn = gizmo_light_radius_prop_matrix_get, + .value_set_fn = gizmo_light_radius_prop_matrix_set, + .range_get_fn = NULL, + .user_data = (void *)C, + }); + } } static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgroup) @@ -165,6 +230,7 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr Object *ob = BKE_view_layer_active_object_get(view_layer); Light *la = ob->data; + /* Spot angle gizmo. */ { PointerRNA lamp_ptr; RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr); @@ -179,6 +245,7 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr WM_gizmo_target_property_def_rna(gz, "offset", &lamp_ptr, propname, -1); } + /* Spot blend gizmo. */ { wmGizmo *gz = ls_gzgroup->spot_blend; @@ -192,6 +259,23 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr } } +static void WIDGETGROUP_light_spot_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) +{ + LightSpotWidgetGroup *ls_gzgroup = gzgroup->customdata; + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer); + Object *ob = BKE_view_layer_active_object_get(view_layer); + + /* Spot radius gizmo. */ + wmGizmo *gz = ls_gzgroup->spot_radius; + + /* Draw circle in the screen space. */ + RegionView3D *rv3d = CTX_wm_region(C)->regiondata; + WM_gizmo_set_matrix_rotation_from_z_axis(gz, rv3d->viewinv[2]); + + WM_gizmo_set_matrix_location(gz, ob->object_to_world[3]); +} + void VIEW3D_GGT_light_spot(wmGizmoGroupType *gzgt) { gzgt->name = "Spot Light Widgets"; @@ -203,6 +287,93 @@ void VIEW3D_GGT_light_spot(wmGizmoGroupType *gzgt) gzgt->setup = WIDGETGROUP_light_spot_setup; gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; gzgt->refresh = WIDGETGROUP_light_spot_refresh; + gzgt->draw_prepare = WIDGETGROUP_light_spot_draw_prepare; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Point Light Gizmo + * \{ */ + +static bool WIDGETGROUP_light_point_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) +{ + const View3D *v3d = CTX_wm_view3d(C); + if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) { + return false; + } + if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_SIZE) == 0) { + return false; + } + + const Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); + const Base *base = BKE_view_layer_active_base_get(view_layer); + if (base && BASE_SELECTABLE(v3d, base)) { + const Object *ob = base->object; + if (ob->type == OB_LAMP) { + const Light *la = ob->data; + return (la->type == LA_LOCAL); + } + } + return false; +} + +static void WIDGETGROUP_light_point_setup(const bContext *C, wmGizmoGroup *gzgroup) +{ + wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); + /* Point radius gizmo. */ + wmGizmo *gz = wwrapper->gizmo; + gzgroup->customdata = wwrapper; + + RNA_enum_set(gz->ptr, + "transform", + ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_CIRCLE); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); + + WM_gizmo_target_property_def_func(gz, + "matrix", + &(const struct wmGizmoPropertyFnParams){ + .value_get_fn = gizmo_light_radius_prop_matrix_get, + .value_set_fn = gizmo_light_radius_prop_matrix_set, + .range_get_fn = NULL, + .user_data = (void *)C, + }); +} + +static void WIDGETGROUP_light_point_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) +{ + wmGizmoWrapper *wwrapper = gzgroup->customdata; + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer); + const Object *ob = BKE_view_layer_active_object_get(view_layer); + + /* Point radius gizmo. */ + wmGizmo *gz = wwrapper->gizmo; + + /* Draw circle in the screen space. */ + const RegionView3D *rv3d = CTX_wm_region(C)->regiondata; + WM_gizmo_set_matrix_rotation_from_z_axis(gz, rv3d->viewinv[2]); + + WM_gizmo_set_matrix_location(gz, ob->object_to_world[3]); +} + +void VIEW3D_GGT_light_point(wmGizmoGroupType *gzgt) +{ + gzgt->name = "Point Light Widgets"; + gzgt->idname = "VIEW3D_GGT_light_point"; + + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D); + + gzgt->poll = WIDGETGROUP_light_point_poll; + gzgt->setup = WIDGETGROUP_light_point_setup; + gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; + gzgt->draw_prepare = WIDGETGROUP_light_point_draw_prepare; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc index 86aecfb6c34..b3310f6084b 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc +++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc @@ -46,9 +46,9 @@ /** * Check if drawing should be performed, clear the pre-selection in the case it's disabled. - * Without this, the gizmo would be visible while transforming. See T92954. + * Without this, the gizmo would be visible while transforming. See #92954. * - * NOTE(@campbellbarton): This is a workaround for the gizmo system, since typically poll + * NOTE(@ideasman42): This is a workaround for the gizmo system, since typically poll * would be used for this purpose. The problem with using poll is once the gizmo is visible again * is there is a visible flicker showing the previous location before cursor motion causes the * pre selection to be updated. While this is only a glitch, it's distracting. diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index b9a30eac3c6..4ab1e1d4ae4 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -467,7 +467,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C, * in 3.0 this happened because left-click drag would both select and add a new ruler, * significantly increasing the likelihood of this happening. * Workaround this crash by checking the gizmo's custom-data has not been cleared. - * The key-map has also been modified not to trigger this bug, see T95591. + * The key-map has also been modified not to trigger this bug, see #95591. */ static bool gizmo_ruler_check_for_operator(const wmGizmoGroup *gzgroup) { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c index aa287403e23..3519a30e222 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c @@ -50,7 +50,7 @@ static bool WIDGETGROUP_tool_generic_poll(const bContext *C, wmGizmoGroupType *g return false; } - /* Without this, refreshing the gizmo jitters in some cases with edit-mesh smooth. See T72948. */ + /* Without this, refreshing the gizmo jitters in some cases with edit-mesh smooth. See #72948. */ if (G.moving & G_TRANSFORM_EDIT) { return false; } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index bfc2cf5214a..b94833dd276 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -212,6 +212,7 @@ extern const char *view3d_context_dir[]; /* doc access */ /* view3d_widgets.c */ void VIEW3D_GGT_light_spot(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_light_point(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_light_area(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_light_target(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_camera(struct wmGizmoGroupType *gzgt); @@ -235,7 +236,7 @@ void VIEW3D_GT_navigate_rotate(struct wmGizmoType *gzt); void VIEW3D_GGT_placement(struct wmGizmoGroupType *gzgt); /* workaround for trivial but noticeable camera bug caused by imprecision - * between view border calculation in 2D/3D space, workaround for bug T28037. + * between view border calculation in 2D/3D space, workaround for bug #28037. * without this define we get the old behavior which is to try and align them * both which _mostly_ works fine, but when the camera moves beyond ~1000 in * any direction it starts to fail */ diff --git a/source/blender/editors/space_view3d/view3d_iterators.cc b/source/blender/editors/space_view3d/view3d_iterators.cc index 09ff3fa6574..e7e8eb5b275 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.cc +++ b/source/blender/editors/space_view3d/view3d_iterators.cc @@ -96,7 +96,7 @@ static int content_planes_from_clip_flag(const ARegion *region, * Edge projection is more involved since part of the edge may be behind the view * or extend beyond the far limits. In the case of single points, these can be ignored. * However it just may still be visible on screen, so constrained the edge to planes - * defined by the port to ensure both ends of the edge can be projected, see T32214. + * defined by the port to ensure both ends of the edge can be projected, see #32214. * * \note This is unrelated to #V3D_PROJ_TEST_CLIP_BB which must be checked separately. */ @@ -577,12 +577,13 @@ void mesh_foreachScreenFace( BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE); - if (me->runtime->subsurf_face_dot_tags.size() == me->totvert) { - BKE_mesh_foreach_mapped_face_center( + const int face_dot_tags_num = me->runtime->subsurf_face_dot_tags.size(); + if (face_dot_tags_num && (face_dot_tags_num != me->totvert)) { + BKE_mesh_foreach_mapped_subdiv_face_center( me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); } else { - BKE_mesh_foreach_mapped_subdiv_face_center( + BKE_mesh_foreach_mapped_face_center( me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); } } diff --git a/source/blender/editors/space_view3d/view3d_navigate.c b/source/blender/editors/space_view3d/view3d_navigate.c index ed0225f578b..9f4710b28a0 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.c +++ b/source/blender/editors/space_view3d/view3d_navigate.c @@ -819,7 +819,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) * object, but in this case there is no change in the scene, * only the cursor so I choice a ED_region_tag like * view3d_smooth_view do for the center_cursor. - * See bug T22640. + * See bug #22640. */ return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/view3d_navigate_ndof.c b/source/blender/editors/space_view3d/view3d_navigate_ndof.c index 9fb33013c4e..0ddfa8dc0f3 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_ndof.c +++ b/source/blender/editors/space_view3d/view3d_navigate_ndof.c @@ -382,7 +382,7 @@ static int view3d_ndof_cameraview_pan_zoom(bContext *C, const wmEvent *event) * #ED_view3d_camera_view_pan already takes the zoom level into account. */ mul_v2_fl(pan_vec, pan_speed); - /* NOTE(@campbellbarton): In principle rotating could pass through to regular + /* NOTE(@ideasman42): In principle rotating could pass through to regular * non-camera NDOF behavior (exiting the camera-view and rotating). * Disabled this block since in practice it's difficult to control NDOF devices * to perform some rotation with absolutely no translation. Causing rotation to @@ -549,7 +549,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev } } else { - /* NOTE: based on feedback from T67579, users want to have pan and orbit enabled at once. + /* NOTE: based on feedback from #67579, users want to have pan and orbit enabled at once. * It's arguable that orbit shouldn't pan (since we have a pan only operator), * so if there are users who like to separate orbit/pan operations - it can be a preference. */ const bool is_orbit_around_pivot = (U.ndof_flag & NDOF_MODE_ORBIT) || diff --git a/source/blender/editors/space_view3d/view3d_navigate_roll.c b/source/blender/editors/space_view3d/view3d_navigate_roll.c index 51b92cb23b3..266fafaec9e 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_roll.c +++ b/source/blender/editors/space_view3d/view3d_navigate_roll.c @@ -109,7 +109,7 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event) } else if (event->type == vod->init.event_type) { /* Check `vod->init.event_type` first in case RMB was used to invoke. - * in this case confirming takes precedence over canceling, see: T102937. */ + * in this case confirming takes precedence over canceling, see: #102937. */ if (event->val == KM_RELEASE) { event_code = VIEW_CONFIRM; } diff --git a/source/blender/editors/space_view3d/view3d_navigate_smoothview.c b/source/blender/editors/space_view3d/view3d_navigate_smoothview.c index a5eee436fdb..9b4e652ad63 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_smoothview.c +++ b/source/blender/editors/space_view3d/view3d_navigate_smoothview.c @@ -35,7 +35,7 @@ static void view3d_smoothview_apply_with_interp( * undo is pushed then the change is rewound, and smooth-view completes from it's timer. * In the case smooth-view executed the change immediately - an undo push is called. * - * NOTE(@campbellbarton): While this is not ideal it's necessary as making the undo-push + * NOTE(@ideasman42): While this is not ideal it's necessary as making the undo-push * once smooth-view is complete because smooth-view is non-blocking and it's possible other * operations are executed once smooth-view has started. * \{ */ @@ -85,7 +85,7 @@ void ED_view3d_smooth_view_undo_end(bContext *C, return; } - /* NOTE(@campbellbarton): It is not possible that a single viewport references different cameras + /* NOTE(@ideasman42): It is not possible that a single viewport references different cameras * so even in the case there is a quad-view with multiple camera views set, these will all * reference the same camera. In this case it doesn't matter which region is used. * If in the future multiple cameras are supported, this logic can be extended. */ diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index b8c744f1c56..054137fd837 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -1303,6 +1303,7 @@ static bool view3d_lasso_select(bContext *C, const int mcoords_len, const eSelectOp sel_op) { + using namespace blender; Object *ob = CTX_data_active_object(C); bool changed_multi = false; @@ -1362,6 +1363,23 @@ static bool view3d_lasso_select(bContext *C, case OB_MBALL: changed = do_lasso_select_meta(vc, mcoords, mcoords_len, sel_op); break; + case OB_CURVES: { + Curves &curves_id = *static_cast(vc->obedit->data); + bke::CurvesGeometry &curves = curves_id.geometry.wrap(); + changed = ed::curves::select_lasso( + *vc, + curves, + eAttrDomain(curves_id.selection_domain), + Span(reinterpret_cast(mcoords), mcoords_len), + sel_op); + if (changed) { + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a + * generic attribute for now. */ + DEG_id_tag_update(static_cast(vc->obedit->data), ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, vc->obedit->data); + } + break; + } default: BLI_assert_msg(0, "lasso select on incorrect object type"); break; @@ -1989,7 +2007,7 @@ static int selectbuffer_ret_hits_5(GPUSelectResult *buffer, * * \param do_nearest_xray_if_supported: When set, read in hits that don't stop * at the nearest surface. The hits must still be ordered by depth. - * Needed so we can step to the next, non-active object when it's already selected, see: T76445. + * Needed so we can step to the next, non-active object when it's already selected, see: #76445. */ static int mixed_bones_object_selectbuffer(ViewContext *vc, GPUSelectResult *buffer, @@ -2596,7 +2614,7 @@ static bool ed_object_select_pick(bContext *C, ViewLayer *view_layer = vc.view_layer; BKE_view_layer_synced_ensure(scene, view_layer); - /* Don't set when the context has no active object (hidden), see: T60807. */ + /* Don't set when the context has no active object (hidden), see: #60807. */ const Base *oldbasact = vc.obact ? BKE_view_layer_active_base_get(view_layer) : nullptr; /* Always start list from `basact` when cycling the selection. */ Base *startbase = (oldbasact && oldbasact->next) ? @@ -2610,7 +2628,7 @@ static bool ed_object_select_pick(bContext *C, /* For the most part this is equivalent to `(object_mode & OB_MODE_POSE) != 0` * however this logic should also run with weight-paint + pose selection. * Without this, selection in weight-paint mode can de-select armatures which isn't useful, - * see: T101686. */ + * see: #101686. */ const bool has_pose_old = (oldbasact && BKE_object_pose_armature_get_with_wpaint_check(oldbasact->object)); @@ -3010,7 +3028,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op) if (obedit && enumerate) { /* Enumerate makes no sense in edit-mode unless also explicitly picking objects or bones. - * Pass the event through so the event may be handled by loop-select for e.g. see: T100204. */ + * Pass the event through so the event may be handled by loop-select for e.g. see: #100204. */ if (obedit->type != OB_ARMATURE) { return OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED; } @@ -3135,8 +3153,8 @@ void VIEW3D_OT_select(wmOperatorType *ot) ot->srna, "object", false, "Object", "Use object selection (edit mode only)"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - /* Needed for select-through to usefully drag handles, see: T98254. - * NOTE: this option may be removed and become default behavior, see design task: T98552. */ + /* Needed for select-through to usefully drag handles, see: #98254. + * NOTE: this option may be removed and become default behavior, see design task: #98552. */ prop = RNA_def_boolean(ot->srna, "vert_without_handles", false, @@ -3550,7 +3568,8 @@ static bool do_mesh_box_select(ViewContext *vc, } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both use_zbuf and non-use_zbuf versions (need screen cos for both) */ - struct BoxSelectUserData_ForMeshEdge cb_data {}; + struct BoxSelectUserData_ForMeshEdge cb_data { + }; cb_data.data = &data; cb_data.esel = use_zbuf ? esel : nullptr; cb_data.backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem( @@ -3777,7 +3796,7 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const } } - /* The draw order doesn't always match the order we populate the engine, see: T51695. */ + /* The draw order doesn't always match the order we populate the engine, see: #51695. */ qsort(buffer, hits, sizeof(GPUSelectResult), opengl_bone_select_buffer_cmp); for (const GPUSelectResult *buf_iter = buffer, *buf_end = buf_iter + hits; buf_iter < buf_end; @@ -3838,7 +3857,7 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e if (hits > 0) { /* no need to loop if there's no hit */ - /* The draw order doesn't always match the order we populate the engine, see: T51695. */ + /* The draw order doesn't always match the order we populate the engine, see: #51695. */ qsort(buffer, hits, sizeof(GPUSelectResult), opengl_bone_select_buffer_cmp); for (const GPUSelectResult *buf_iter = buffer, *buf_end = buf_iter + hits; buf_iter < buf_end; @@ -3892,6 +3911,7 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e static int view3d_box_select_exec(bContext *C, wmOperator *op) { + using namespace blender; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewContext vc; rcti rect; @@ -3954,6 +3974,19 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); } break; + case OB_CURVES: { + Curves &curves_id = *static_cast(vc.obedit->data); + bke::CurvesGeometry &curves = curves_id.geometry.wrap(); + changed = ed::curves::select_box( + vc, curves, eAttrDomain(curves_id.selection_domain), rect, sel_op); + if (changed) { + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a + * generic attribute for now. */ + DEG_id_tag_update(static_cast(vc.obedit->data), ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, vc.obedit->data); + } + break; + } default: BLI_assert_msg(0, "box select on incorrect object type"); break; @@ -4686,6 +4719,7 @@ static bool obedit_circle_select(bContext *C, const int mval[2], float rad) { + using namespace blender; bool changed = false; BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB)); switch (vc->obedit->type) { @@ -4708,6 +4742,20 @@ static bool obedit_circle_select(bContext *C, case OB_MBALL: changed = mball_circle_select(vc, sel_op, mval, rad); break; + case OB_CURVES: { + Curves &curves_id = *static_cast(vc->obedit->data); + bke::CurvesGeometry &curves = curves_id.geometry.wrap(); + changed = ed::curves::select_circle( + *vc, curves, eAttrDomain(curves_id.selection_domain), mval, rad, sel_op); + if (changed) { + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a + * generic attribute for now. */ + DEG_id_tag_update(static_cast(vc->obedit->data), ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, vc->obedit->data); + } + break; + } + default: BLI_assert(0); break; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index c630a1a5653..4cc282a1cab 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -329,7 +329,7 @@ void view3d_winmatrix_set(Depsgraph *depsgraph, clipend); #endif - /* Note the code here was tweaked to avoid an apparent compiler bug in clang 13 (see T91680). */ + /* Note the code here was tweaked to avoid an apparent compiler bug in clang 13 (see #91680). */ rctf viewplane; if (rect) { /* Smaller viewplane subset for selection picking. */ @@ -667,7 +667,7 @@ int view3d_opengl_select_ex(ViewContext *vc, G.f |= G_FLAG_PICKSEL; /* Important we use the 'viewmat' and don't re-calculate since - * the object & bone view locking takes 'rect' into account, see: T51629. */ + * the object & bone view locking takes 'rect' into account, see: #51629. */ ED_view3d_draw_setup_view( wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, &rect); @@ -702,7 +702,7 @@ int view3d_opengl_select_ex(ViewContext *vc, object_filter.user_data); hits = drw_select_loop_user_data.hits; /* FIX: This cleanup the state before doing another selection pass. - * (see T56695) */ + * (see #56695) */ GPU_select_cache_end(); } diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index f5985a4729b..87da287d6a3 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -47,14 +47,14 @@ set(SRC transform_convert_object_texspace.c transform_convert_paintcurve.c transform_convert_particle.c - transform_convert_sculpt.c + transform_convert_sculpt.cc transform_convert_sequencer.c transform_convert_sequencer_image.c transform_convert_tracking.c transform_draw_cursors.c transform_generics.c transform_gizmo_2d.c - transform_gizmo_3d.c + transform_gizmo_3d.cc transform_gizmo_extrude_3d.c transform_input.c transform_mode.c diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 3c95d480b78..398e8257329 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -343,7 +343,7 @@ void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV adr[1] = vec[1]; } else if (t->region->regiontype == RGN_TYPE_WINDOW) { - /* allow points behind the view T33643. */ + /* allow points behind the view #33643. */ if (ED_view3d_project_float_global(t->region, vec, adr, flag) != V3D_PROJ_RET_OK) { /* XXX, 2.64 and prior did this, weak! */ adr[0] = t->region->winx / 2.0f; @@ -989,7 +989,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) } } else if (transform_mode_is_changeable(t->mode)) { - /* Scale isn't normally very useful after extrude along normals, see T39756 */ + /* Scale isn't normally very useful after extrude along normals, see #39756 */ if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) { stopConstraint(t); } @@ -1302,7 +1302,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) /* Per transform event, if present */ if (t->handleEvent && (!handled || - /* Needed for vertex slide, see T38756. */ + /* Needed for vertex slide, see #38756. */ (event->type == MOUSEMOVE))) { t->redraw |= t->handleEvent(t, event); } @@ -1377,7 +1377,7 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa static bool transinfo_show_overlay(const struct bContext *C, TransInfo *t, ARegion *region) { - /* Don't show overlays when not the active view and when overlay is disabled: T57139 */ + /* Don't show overlays when not the active view and when overlay is disabled: #57139 */ bool ok = false; if (region == t->region) { ok = true; @@ -1859,7 +1859,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve * * Do this only for translation/rotation/resize because only these * modes are available from gizmo and doing such check could - * lead to keymap conflicts for other modes (see T31584) + * lead to keymap conflicts for other modes (see #31584) */ if (ELEM(mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) { LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &t->keymap->items) { diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index d548cf631f1..dede02b219f 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -211,6 +211,12 @@ typedef enum { HLP_TRACKBALL = 6, } eTHelpline; +typedef enum { + O_DEFAULT = 0, + O_SCENE, + O_SET, +} eTOType; + /** \} */ /* -------------------------------------------------------------------- */ @@ -607,11 +613,7 @@ typedef struct TransInfo { float matrix[3][3]; } orient[3]; - enum { - O_DEFAULT = 0, - O_SCENE, - O_SET, - } orient_curr; + eTOType orient_curr; /** * All values from `TransInfo.orient[].type` converted into a flag diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 095c59f783b..802851246c0 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -421,7 +421,7 @@ static void applyAxisConstraintVec(const TransInfo *t, constraint_snap_plane_to_edge(t, plane, out); } else if (is_snap_to_face) { - /* Disabled, as it has not proven to be really useful. (See T82386). */ + /* Disabled, as it has not proven to be really useful. (See #82386). */ // constraint_snap_plane_to_face(t, plane, out); } else if (!isPlaneProjectionViewAligned(t, plane)) { @@ -1165,6 +1165,7 @@ void setNearestAxis(TransInfo *t) if (mode_prev != t->con.mode) { projection_matrix_calc(t, t->con.pmtx); + transform_gizmo_3d_model_from_constraint_and_mode_set(t); } } diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index a2161daa58c..211b72c0e77 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -566,7 +566,7 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list) /* constraints that require this only under special conditions */ if (con->type == CONSTRAINT_TYPE_CHILDOF) { - /* ChildOf constraint only works when using all location components, see T42256. */ + /* ChildOf constraint only works when using all location components, see #42256. */ bChildOfConstraint *data = (bChildOfConstraint *)con->data; if ((data->flag & CHILDOF_LOCX) && (data->flag & CHILDOF_LOCY) && @@ -609,7 +609,7 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list) } else if (con->type == CONSTRAINT_TYPE_TRANSFORM) { /* Transform constraint needs it for rotation at least (r.57309), - * but doing so when translating may also mess things up, see: T36203. */ + * but doing so when translating may also mess things up, see: #36203. */ bTransformConstraint *data = (bTransformConstraint *)con->data; if (data->to == TRANS_ROTATION) { @@ -709,7 +709,7 @@ static int countAndCleanTransDataContainer(TransInfo *t) static void init_proportional_edit(TransInfo *t) { - /* NOTE: Proportional editing is not usable in pose mode yet T32444. */ + /* NOTE: Proportional editing is not usable in pose mode yet #32444. */ if (!ELEM(t->data_type, &TransConvertType_Action, &TransConvertType_Curve, @@ -1021,7 +1021,7 @@ void createTransData(bContext *C, TransInfo *t) if (t->data_type == &TransConvertType_Object) { t->options |= CTX_OBJECT; - /* Needed for correct Object.obmat after duplication, see: T62135. */ + /* Needed for correct Object.obmat after duplication, see: #62135. */ BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context)); if ((t->settings->transform_flag & SCE_XFORM_DATA_ORIGIN) != 0) { @@ -1196,7 +1196,7 @@ void animrecord_check_state(TransInfo *t, struct ID *id) /* copy current "action blending" settings from adt to the strip, * as it was keyframed with these settings, so omitting them will - * change the effect [T54766] + * change the effect [#54766] */ if (is_first == false) { strip->blendmode = adt->act_blendmode; diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index 126f29f4fb4..a9eee34e8b6 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -260,7 +260,7 @@ extern TransConvertTypeInfo TransConvertType_PaintCurve; extern TransConvertTypeInfo TransConvertType_Particle; -/* transform_convert_sculpt.c */ +/* transform_convert_sculpt.cc */ extern TransConvertTypeInfo TransConvertType_Sculpt; diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 31d0dea3b96..43fffdc634a 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -338,7 +338,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) copy_v3_v3(data->grabtarget, pchan->pose_tail); /* watch-it! has to be 0 here, since we're still on the - * same bone for the first time through the loop T25885. */ + * same bone for the first time through the loop #25885. */ data->rootbone = 0; /* we only include bones that are part of a continual connected chain */ @@ -1051,9 +1051,9 @@ static void createTransArmatureVerts(bContext *UNUSED(C), TransInfo *t) copy_v3_v3(td->iloc, ebo->tail); /* Don't allow single selected tips to have a modified center, - * causes problem with snapping (see T45974). + * causes problem with snapping (see #45974). * However, in rotation mode, we want to keep that 'rotate bone around root with - * only its tip selected' behavior (see T46325). */ + * only its tip selected' behavior (see #46325). */ if ((t->around == V3D_AROUND_LOCAL_ORIGINS) && ((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL))) { copy_v3_v3(td->center, ebo->head); @@ -1271,7 +1271,7 @@ static void recalcData_edit_armature(TransInfo *t) rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec); mul_qt_v3(qrot, up_axis); - /* roll has a tendency to flip in certain orientations - T34283, T33974. */ + /* roll has a tendency to flip in certain orientations - #34283, #33974. */ roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false); ebo->roll = angle_compat_rad(roll, td->ival); } @@ -1612,7 +1612,7 @@ static short apply_targetless_ik(Object *ob) normalize_m3(rmat3); /* rotation */ - /* T22409 is partially caused by this, as slight numeric error introduced during + /* #22409 is partially caused by this, as slight numeric error introduced during * the solving process leads to locked-axis values changing. However, we cannot modify * the values here, or else there are huge discrepancies between IK-solver (interactive) * and applied poses. */ @@ -1712,7 +1712,7 @@ static void special_aftertrans_update__pose(bContext *C, TransInfo *t) if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) { /* when running transform non-interactively (operator exec), * we need to update the pose otherwise no updates get called during - * transform and the auto-ik is not applied. see T26164. */ + * transform and the auto-ik is not applied. see #26164. */ struct Object *pose_ob = tc->poseobj; BKE_pose_where_is(t->depsgraph, t->scene, pose_ob); } diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index b3ee49ef7ed..8d1727e7ac7 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -48,7 +48,7 @@ static int bezt_select_to_transform_triple_flag(const BezTriple *bezt, const boo * When a center point is being moved without the handles, * leaving the handles stationary makes no sense and only causes strange behavior, * where one handle is arbitrarily anchored, the other one is aligned and lengthened - * based on where the center point is moved. Also a bug when canceling, see: T52007. + * based on where the center point is moved. Also a bug when canceling, see: #52007. * * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'. * However that doesn't resolve odd behavior, so best transform the handles in this case. @@ -437,7 +437,7 @@ static void recalcData_curve(TransInfo *t) } } else { - /* Apply clipping after so we never project past the clip plane T25423. */ + /* Apply clipping after so we never project past the clip plane #25423. */ transform_convert_clip_mirror_modifier_apply(tc); /* Normal updating. */ diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index f7ce586df39..902b995680f 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -556,7 +556,7 @@ static void tc_mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tc * * Since we only need to check if the vertex is in this corner, * its not important _which_ loop - as long as its not overlapping - * 'sv->co_orig_3d', see: T45096. */ + * 'sv->co_orig_3d', see: #45096. */ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis); while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) && ((l_prev = l_prev->prev) != l->next))) { @@ -1321,7 +1321,7 @@ void transform_convert_mesh_crazyspace_detect(TransInfo *t, * correction with \a quats, relative to the coordinates after * the modifiers that support deform matrices \a defcos. */ -#if 0 /* TODO(@campbellbarton): fix crazy-space & extrude so it can be enabled for general use. \ +#if 0 /* TODO(@ideasman42): fix crazy-space & extrude so it can be enabled for general use. \ */ if ((totleft > 0) || (totleft == -1)) #else @@ -1508,7 +1508,7 @@ static void createTransEditVerts(bContext *UNUSED(C), TransInfo *t) } /* Snap rotation along normal needs a common axis for whole islands, - * otherwise one get random crazy results, see T59104. + * otherwise one get random crazy results, see #59104. * However, we do not want to use the island center for the pivot/translation reference. */ const bool is_snap_rotate = ((t->mode == TFM_TRANSLATION) && /* There is not guarantee that snapping @@ -1517,7 +1517,7 @@ static void createTransEditVerts(bContext *UNUSED(C), TransInfo *t) (t->settings->snap_flag & SCE_SNAP_ROTATE) != 0) && (t->around != V3D_AROUND_LOCAL_ORIGINS)); - /* Even for translation this is needed because of island-orientation, see: T51651. */ + /* Even for translation this is needed because of island-orientation, see: #51651. */ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) || is_snap_rotate; if (is_island_center) { /* In this specific case, near-by vertices will need to know @@ -2046,7 +2046,7 @@ static void recalcData_mesh(TransInfo *t) bool do_mirror = !(t->flag & T_NO_MIRROR); FOREACH_TRANS_DATA_CONTAINER (t, tc) { - /* Apply clipping after so we never project past the clip plane T25423. */ + /* Apply clipping after so we never project past the clip plane #25423. */ transform_convert_clip_mirror_modifier_apply(tc); if (do_mirror) { @@ -2131,7 +2131,7 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) FOREACH_TRANS_DATA_CONTAINER (t, tc) { /* table needs to be created for each edit command, since vertices can move etc */ ED_mesh_mirror_spatial_table_end(tc->obedit); - /* TODO(@campbellbarton): xform: We need support for many mirror objects at once! */ + /* TODO(@ideasman42): xform: We need support for many mirror objects at once! */ break; } } diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index f38d25b440b..a9b1d07e7b4 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -67,7 +67,7 @@ typedef struct TransDataNla { static void applyTransformNLA_translation(PointerRNA *strip_rna_ptr, const TransDataNla *transdata) { /* NOTE: we write these twice to avoid truncation errors which can arise when - * moving the strips a large distance using numeric input T33852. + * moving the strips a large distance using numeric input #33852. */ RNA_float_set(strip_rna_ptr, "frame_start", transdata->h1[0]); RNA_float_set(strip_rna_ptr, "frame_end", transdata->h2[0]); @@ -457,7 +457,7 @@ static void recalcData_nla(TransInfo *t) if (BKE_nlatrack_has_space(track, strip->start, strip->end) && !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, track)) { /* move strip to this track */ - BLI_remlink(&tdn->nlt->strips, strip); + BKE_nlatrack_remove_strip(tdn->nlt, strip); BKE_nlatrack_add_strip(track, strip, is_liboverride); tdn->nlt = track; @@ -477,7 +477,7 @@ static void recalcData_nla(TransInfo *t) if (BKE_nlatrack_has_space(track, strip->start, strip->end) && !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, track)) { /* move strip to this track */ - BLI_remlink(&tdn->nlt->strips, strip); + BKE_nlatrack_remove_strip(tdn->nlt, strip); BKE_nlatrack_add_strip(track, strip, is_liboverride); tdn->nlt = track; diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 045b737c4f7..a0364642d1f 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -211,7 +211,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) copy_m4_m4(ob->object_to_world, object_eval->object_to_world); /* Only copy negative scale flag, this is the only flag which is modified by * the BKE_object_where_is_calc(). The rest of the flags we need to keep, - * otherwise we might lose dupli flags (see T61787). */ + * otherwise we might lose dupli flags (see #61787). */ ob->transflag &= ~OB_NEG_SCALE; ob->transflag |= (object_eval->transflag & OB_NEG_SCALE); @@ -274,7 +274,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) copy_m3_m4(totmat, ob->object_to_world); /* If the object scale is zero on any axis, this might result in a zero matrix. - * In this case, the transformation would not do anything, see: T50103. */ + * In this case, the transformation would not do anything, see: #50103. */ orthogonalize_m3_zero_axes(obmtx, 1.0f); orthogonalize_m3_zero_axes(totmat, 1.0f); @@ -857,7 +857,7 @@ static bool motionpath_need_update_object(Scene *scene, Object *ob) { /* XXX: there's potential here for problems with unkeyed rotations/scale, * but for now (until proper data-locality for baking operations), - * this should be a better fix for T24451 and T37755 + * this should be a better fix for #24451 and #37755 */ if (autokeyframe_cfra_can_key(scene, &ob->id)) { diff --git a/source/blender/editors/transform/transform_convert_sculpt.c b/source/blender/editors/transform/transform_convert_sculpt.cc similarity index 93% rename from source/blender/editors/transform/transform_convert_sculpt.c rename to source/blender/editors/transform/transform_convert_sculpt.cc index cdd46e08c5c..7872bc03196 100644 --- a/source/blender/editors/transform/transform_convert_sculpt.c +++ b/source/blender/editors/transform/transform_convert_sculpt.cc @@ -43,8 +43,8 @@ static void createTransSculpt(bContext *C, TransInfo *t) TransDataContainer *tc = t->data_container; tc->data_len = 1; tc->is_active = 1; - td = tc->data = MEM_callocN(sizeof(TransData), "TransSculpt"); - td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransSculpt"); + td = tc->data = MEM_cnew(__func__); + td->ext = tc->data_ext = MEM_cnew(__func__); } td->flag = TD_SELECTED; @@ -63,9 +63,9 @@ static void createTransSculpt(bContext *C, TransInfo *t) copy_m3_m4(obmat_inv, ob->object_to_world); invert_m3(obmat_inv); - td->ext->rot = NULL; - td->ext->rotAxis = NULL; - td->ext->rotAngle = NULL; + td->ext->rot = nullptr; + td->ext->rotAxis = nullptr; + td->ext->rotAngle = nullptr; td->ext->quat = ss->pivot_rot; copy_m4_m4(td->ext->obmat, ob->object_to_world); copy_m3_m3(td->ext->l_smtx, obmat_inv); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index d1f210ca772..48edf180a81 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -512,7 +512,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } else { - /* Release confirms preference should not affect node editor (T69288, T70504). */ + /* Release confirms preference should not affect node editor (#69288, #70504). */ if (ISMOUSE_BUTTON(t->launch_event) && ((U.flag & USER_RELEASECONFIRM) || (t->spacetype == SPACE_NODE))) { /* Global "release confirm" on mouse bindings */ @@ -1422,7 +1422,7 @@ Object *transform_object_deform_pose_armature_get(const TransInfo *t, Object *ob if (!(ob->mode & OB_MODE_ALL_WEIGHT_PAINT)) { return NULL; } - /* Important that ob_armature can be set even when its not selected T23412. + /* Important that ob_armature can be set even when its not selected #23412. * Lines below just check is also visible. */ Object *ob_armature = BKE_modifiers_is_deformed_by_armature(ob); if (ob_armature && ob_armature->mode & OB_MODE_POSE) { diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.cc similarity index 89% rename from source/blender/editors/transform/transform_gizmo_3d.c rename to source/blender/editors/transform/transform_gizmo_3d.cc index e1afea1e05d..157a80e4146 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.cc @@ -8,10 +8,10 @@ * Used for 3D View */ -#include -#include -#include -#include +#include +#include +#include +#include #include "DNA_armature_types.h" #include "DNA_curve_types.h" @@ -70,8 +70,8 @@ #include "GPU_state.h" -static wmGizmoGroupType *g_GGT_xform_gizmo = NULL; -static wmGizmoGroupType *g_GGT_xform_gizmo_context = NULL; +static wmGizmoGroupType *g_GGT_xform_gizmo = nullptr; +static wmGizmoGroupType *g_GGT_xform_gizmo_context = nullptr; static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup, const float twmat[4][4], @@ -148,7 +148,7 @@ enum { MAN_AXES_SCALE, }; -typedef struct GizmoGroup { +struct GizmoGroup { bool all_hidden; int twtype; @@ -165,8 +165,8 @@ typedef struct GizmoGroup { /* Only for Rotate operator. */ float rotation; - struct wmGizmo *gizmos[MAN_AXIS_LAST]; -} GizmoGroup; + wmGizmo *gizmos[MAN_AXIS_LAST]; +}; /* -------------------------------------------------------------------- */ /** \name Utilities @@ -187,7 +187,7 @@ typedef struct GizmoGroup { static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *ggd, const short axis_idx) { - BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST)); + BLI_assert(IN_RANGE_INCL(axis_idx, float(MAN_AXIS_TRANS_X), float(MAN_AXIS_LAST))); return ggd->gizmos[axis_idx]; } @@ -434,7 +434,7 @@ static void gizmo_get_axis_constraint(const int axis_idx, bool r_axis[3]) /* **************** Preparation Stuff **************** */ -static void reset_tw_center(struct TransformBounds *tbounds) +static void reset_tw_center(TransformBounds *tbounds) { INIT_MINMAX(tbounds->min, tbounds->max); zero_v3(tbounds->center); @@ -446,7 +446,7 @@ static void reset_tw_center(struct TransformBounds *tbounds) } /* transform widget center calc helper for below */ -static void calc_tw_center(struct TransformBounds *tbounds, const float co[3]) +static void calc_tw_center(TransformBounds *tbounds, const float co[3]) { minmax_v3v3_v3(tbounds->min, tbounds->max, co); add_v3_v3(tbounds->center, co); @@ -458,7 +458,7 @@ static void calc_tw_center(struct TransformBounds *tbounds, const float co[3]) } } -static void calc_tw_center_with_matrix(struct TransformBounds *tbounds, +static void calc_tw_center_with_matrix(TransformBounds *tbounds, const float co[3], const bool use_matrix, const float matrix[4][4]) @@ -620,8 +620,8 @@ bool gimbal_axis_object(Object *ob, float gmat[3][3]) } int ED_transform_calc_gizmo_stats(const bContext *C, - const struct TransformCalcParams *params, - struct TransformBounds *tbounds) + const TransformCalcParams *params, + TransformBounds *tbounds) { ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); @@ -630,8 +630,8 @@ int ED_transform_calc_gizmo_stats(const bContext *C, * Is it fine to possibly evaluate dependency graph here? */ Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); ViewLayer *view_layer = CTX_data_view_layer(C); - View3D *v3d = area->spacedata.first; - RegionView3D *rv3d = region->regiondata; + View3D *v3d = static_cast(area->spacedata.first); + RegionView3D *rv3d = static_cast(region->regiondata); Base *base; bGPdata *gpd = CTX_data_gpencil_data(C); const bool is_gp_edit = GPENCIL_ANY_MODE(gpd); @@ -648,7 +648,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, Object *obedit = OBEDIT_FROM_OBACT(ob); if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) { Object *obpose = BKE_object_pose_armature_get(ob); - if (obpose != NULL) { + if (obpose != nullptr) { ob = obpose; } } @@ -662,7 +662,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, zero_v3(rv3d->tw_axis_min); zero_v3(rv3d->tw_axis_max); - rv3d->twdrawflag = 0xFFFF; + rv3d->twdrawflag = short(0xFFFF); /* global, local or normal orientation? * if we could check 'totsel' now, this should be skipped with no selection. */ @@ -695,7 +695,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* only editable and visible layers are considered */ - if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { + if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != nullptr)) { /* calculate difference matrix */ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat); @@ -707,7 +707,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } if (is_curve_edit) { - if (gps->editcurve == NULL) { + if (gps->editcurve == nullptr) { continue; } @@ -748,7 +748,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, /* selection center */ if (totsel) { - mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ + mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */ } } else if (obedit) { @@ -800,7 +800,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } /* end editmesh */ else if (obedit->type == OB_ARMATURE) { FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) { - bArmature *arm = ob_iter->data; + bArmature *arm = static_cast(ob_iter->data); float mat_local[4][4]; if (use_mat_local) { @@ -814,7 +814,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } if ((ebo->flag & BONE_ROOTSEL) && /* don't include same point multiple times */ - ((ebo->flag & BONE_CONNECTED) && (ebo->parent != NULL) && + ((ebo->flag & BONE_CONNECTED) && (ebo->parent != nullptr) && (ebo->parent->flag & BONE_TIPSEL) && EBONE_VISIBLE(arm, ebo->parent)) == 0) { calc_tw_center_with_matrix(tbounds, ebo->head, use_mat_local, mat_local); totsel++; @@ -829,8 +829,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) { FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) { - Curve *cu = ob_iter->data; - Nurb *nu; + Curve *cu = static_cast(ob_iter->data); BezTriple *bezt; BPoint *bp; ListBase *nurbs = BKE_curve_editNurbs_get(cu); @@ -840,7 +839,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world); } - nu = nurbs->first; + Nurb *nu = static_cast(nurbs->first); while (nu) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; @@ -936,7 +935,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, /* selection center */ if (totsel) { - mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ + mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */ mul_m4_v3(obedit->object_to_world, tbounds->center); mul_m4_v3(obedit->object_to_world, tbounds->min); mul_m4_v3(obedit->object_to_world, tbounds->max); @@ -974,7 +973,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, MEM_freeN(objects); if (totsel) { - mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ + mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */ mul_m4_v3(ob->object_to_world, tbounds->center); mul_m4_v3(ob->object_to_world, tbounds->min); mul_m4_v3(ob->object_to_world, tbounds->max); @@ -1012,7 +1011,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, /* selection center */ if (totsel) { - mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ + mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */ } } } @@ -1021,26 +1020,27 @@ int ED_transform_calc_gizmo_stats(const bContext *C, /* we need the one selected object, if its not active */ BKE_view_layer_synced_ensure(scene, view_layer); base = BKE_view_layer_active_base_get(view_layer); - ob = base ? base->object : NULL; + ob = base ? base->object : nullptr; if (base && ((base->flag & BASE_SELECTED) == 0)) { - ob = NULL; + ob = nullptr; } - for (base = BKE_view_layer_object_bases_get(view_layer)->first; base; base = base->next) { + for (base = static_cast(BKE_view_layer_object_bases_get(view_layer)->first); base; + base = base->next) { if (!BASE_SELECTED_EDITABLE(v3d, base)) { continue; } - if (ob == NULL) { + if (ob == nullptr) { ob = base->object; } /* Get the boundbox out of the evaluated object. */ - const BoundBox *bb = NULL; + const BoundBox *bb = nullptr; if (params->use_only_center == false) { bb = BKE_object_boundbox_get(base->object); } - if (params->use_only_center || (bb == NULL)) { + if (params->use_only_center || (bb == nullptr)) { calc_tw_center(tbounds, base->object->object_to_world[3]); } else { @@ -1065,7 +1065,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, /* selection center */ if (totsel) { - mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ + mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */ } } @@ -1093,7 +1093,7 @@ static void gizmo_get_idot(const RegionView3D *rv3d, float r_idot[3]) static void gizmo_prepare_mat(const bContext *C, RegionView3D *rv3d, - const struct TransformBounds *tbounds) + const TransformBounds *tbounds) { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1106,7 +1106,7 @@ static void gizmo_prepare_mat(const bContext *C, if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) { BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); - if (ob != NULL) { + if (ob != nullptr) { /* Grease Pencil uses object origin. */ bGPdata *gpd = CTX_data_gpencil_data(C); if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) { @@ -1172,23 +1172,22 @@ static void gizmo_line_range(const int twtype, const short axis_type, float *r_s } static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup, - struct wmMsgBus *mbus, + wmMsgBus *mbus, Scene *scene, bScreen *screen, ScrArea *area, ARegion *region, - const void *type_fn) + void (*type_fn)(wmGizmoGroupType *)) { /* Subscribe to view properties */ - wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = { - .owner = region, - .user_data = gzgroup->parent_gzmap, - .notify = WM_gizmo_do_msg_notify_tag_refresh, - }; + wmMsgSubscribeValue msg_sub_value_gz_tag_refresh{}; + msg_sub_value_gz_tag_refresh.owner = region; + msg_sub_value_gz_tag_refresh.user_data = gzgroup->parent_gzmap; + msg_sub_value_gz_tag_refresh.notify = WM_gizmo_do_msg_notify_tag_refresh; int orient_flag = 0; if (type_fn == VIEW3D_GGT_xform_gizmo) { - GizmoGroup *ggd = gzgroup->customdata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); orient_flag = ggd->twtype_init; } else if (type_fn == VIEW3D_GGT_xform_cage) { @@ -1220,7 +1219,7 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup, /* We could be more specific here, for now subscribe to any cursor change. */ PointerRNA cursor_ptr; RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr); - WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__); + WM_msg_subscribe_rna(mbus, &cursor_ptr, nullptr, &msg_sub_value_gz_tag_refresh, __func__); } { @@ -1263,7 +1262,7 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup, RNA_pointer_create(&screen->id, &RNA_SpaceView3D, area->spacedata.first, &view3d_ptr); if (type_fn == VIEW3D_GGT_xform_gizmo) { - GizmoGroup *ggd = gzgroup->customdata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); if (ggd->use_twtype_refresh) { const PropertyRNA *props[] = { &rna_SpaceView3D_show_gizmo_object_translate, @@ -1327,13 +1326,13 @@ static void gizmo_3d_dial_matrixbasis_calc(const ARegion *region, /** Offset of the two-axis planes, depends on the gizmos scale. Define to avoid repeating. */ #define MAN_AXIS_SCALE_PLANE_OFFSET 7.0f -static void rotation_get_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value) +static void rotation_get_fn(const wmGizmo * /*gz*/, wmGizmoProperty *gz_prop, void *value) { const GizmoGroup *ggd = (const GizmoGroup *)gz_prop->custom_func.user_data; *(float *)value = ggd->rotation; } -static void rotation_set_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value) +static void rotation_set_fn(const wmGizmo * /*gz*/, wmGizmoProperty *gz_prop, const void *value) { GizmoGroup *ggd = (GizmoGroup *)gz_prop->custom_func.user_data; ggd->rotation = *(const float *)value; @@ -1377,7 +1376,7 @@ static void gizmo_3d_setup_draw_default(wmGizmo *axis, const int axis_idx) WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_MODAL, true); WM_gizmo_set_scale(axis, 0.2f); - /* Prevent axis gizmos overlapping the center point, see: T63744. */ + /* Prevent axis gizmos overlapping the center point, see: #63744. */ axis->select_bias = 2.0f; break; case MAN_AXIS_SCALE_C: @@ -1387,7 +1386,7 @@ static void gizmo_3d_setup_draw_default(wmGizmo *axis, const int axis_idx) RNA_float_set(axis->ptr, "arc_inner_factor", 1.0 / 6.0); WM_gizmo_set_scale(axis, 1.2f); - /* Prevent axis gizmos overlapping the center point, see: T63744. */ + /* Prevent axis gizmos overlapping the center point, see: #63744. */ axis->select_bias = -2.0f; break; @@ -1504,31 +1503,31 @@ static void gizmo_3d_setup_draw_modal(wmGizmo *axis, const int axis_idx) static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup) { - GizmoGroup *ggd; - - ggd = MEM_callocN(sizeof(GizmoGroup), "gizmo_data"); + GizmoGroup *ggd = MEM_cnew(__func__); const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true); const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true); - wmGizmoPropertyFnParams params = { - .value_get_fn = rotation_get_fn, .value_set_fn = rotation_set_fn, .user_data = ggd}; + wmGizmoPropertyFnParams params{}; + params.value_get_fn = rotation_get_fn; + params.value_set_fn = rotation_set_fn; + params.user_data = ggd; #define GIZMO_NEW_ARROW(v) \ { \ - ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \ + ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr); \ } \ ((void)0) #define GIZMO_NEW_DIAL(v) \ { \ - ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \ + ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, nullptr); \ WM_gizmo_target_property_def_func(ggd->gizmos[v], "offset", ¶ms); \ } \ ((void)0) #define GIZMO_NEW_PRIM(v) \ { \ - ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, NULL); \ + ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, nullptr); \ } \ ((void)0) @@ -1576,15 +1575,15 @@ static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup) static int gizmo_modal(bContext *C, wmGizmo *widget, const wmEvent *event, - eWM_GizmoFlagTweak UNUSED(tweak_flag)) + eWM_GizmoFlagTweak /*tweak_flag*/) { - /* Avoid unnecessary updates, partially address: T55458. */ + /* Avoid unnecessary updates, partially address: #55458. */ if (ELEM(event->type, TIMER, INBETWEEN_MOUSEMOVE)) { return OPERATOR_RUNNING_MODAL; } ARegion *region = CTX_wm_region(C); - RegionView3D *rv3d = region->regiondata; + RegionView3D *rv3d = static_cast(region->regiondata); wmGizmoGroup *gzgroup = widget->parent_gzgroup; /* Recalculating the orientation has two problems. @@ -1596,55 +1595,56 @@ static int gizmo_modal(bContext *C, * when scaling. */ if (false) { - struct TransformBounds tbounds; + TransformBounds tbounds; - if (ED_transform_calc_gizmo_stats(C, - &(struct TransformCalcParams){ - .use_only_center = true, - }, - &tbounds)) { + TransformCalcParams calc_params{}; + calc_params.use_only_center = true; + if (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds)) { gizmo_prepare_mat(C, rv3d, &tbounds); - for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + for (wmGizmo *gz = static_cast(gzgroup->gizmos.first); gz; gz = gz->next) { WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]); } } } else { wmWindow *win = CTX_wm_window(C); - wmOperator *op = NULL; + wmOperator *op = nullptr; for (int i = 0; i < widget->op_data_len; i++) { wmGizmoOpElem *gzop = WM_gizmo_operator_get(widget, i); op = WM_operator_find_modal_by_type(win, gzop->type); - if (op != NULL) { + if (op != nullptr) { break; } } - if (op != NULL) { - GizmoGroup *ggd = gzgroup->customdata; + if (op != nullptr) { + GizmoGroup *ggd = static_cast(gzgroup->customdata); const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &widget); const short axis_type = gizmo_get_axis_type(axis_idx); float twmat[4][4]; float scale_buf[3]; - float *scale = NULL; + float *scale = nullptr; bool update = false; copy_m4_m4(twmat, rv3d->twmat); if (axis_type == MAN_AXES_SCALE) { scale = scale_buf; - transform_final_value_get(op->customdata, scale, 3); + transform_final_value_get(static_cast(op->customdata), scale, 3); update = true; } else if (axis_type == MAN_AXES_ROTATE) { - transform_final_value_get(op->customdata, &ggd->rotation, 1); + transform_final_value_get( + static_cast(op->customdata), &ggd->rotation, 1); if (widget != ggd->gizmos[MAN_AXIS_ROT_C]) { ggd->rotation *= -1; } RNA_float_set( - widget->ptr, "incremental_angle", transform_snap_increment_get(op->customdata)); + widget->ptr, + "incremental_angle", + transform_snap_increment_get(static_cast(op->customdata))); } - else if (transform_apply_matrix(op->customdata, twmat)) { + else if (transform_apply_matrix(static_cast(op->customdata), twmat)) { update = true; } @@ -1662,13 +1662,13 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup) { struct { wmOperatorType *translate, *rotate, *trackball, *resize; - } ot_store = {NULL}; - GizmoGroup *ggd = gzgroup->customdata; + } ot_store = {nullptr}; + GizmoGroup *ggd = static_cast(gzgroup->customdata); MAN_ITER_AXES_BEGIN (axis, axis_idx) { const short axis_type = gizmo_get_axis_type(axis_idx); bool constraint_axis[3] = {1, 0, 0}; - PointerRNA *ptr = NULL; + PointerRNA *ptr = nullptr; gizmo_get_axis_constraint(axis_idx, constraint_axis); @@ -1679,33 +1679,33 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup) switch (axis_type) { case MAN_AXES_TRANSLATE: - if (ot_store.translate == NULL) { + if (ot_store.translate == nullptr) { ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true); } - ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, NULL); + ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, nullptr); break; case MAN_AXES_ROTATE: { wmOperatorType *ot_rotate; if (axis_idx == MAN_AXIS_ROT_T) { - if (ot_store.trackball == NULL) { + if (ot_store.trackball == nullptr) { ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true); } ot_rotate = ot_store.trackball; } else { - if (ot_store.rotate == NULL) { + if (ot_store.rotate == nullptr) { ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true); } ot_rotate = ot_store.rotate; } - ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, NULL); + ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, nullptr); break; } case MAN_AXES_SCALE: { - if (ot_store.resize == NULL) { + if (ot_store.resize == nullptr) { ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true); } - ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, NULL); + ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, nullptr); break; } } @@ -1776,7 +1776,7 @@ static void gizmo_refresh_from_matrix(wmGizmo *axis, const float scale[3]) { const short axis_type = gizmo_get_axis_type(axis_idx); - const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL); + const int aidx_norm = gizmo_orientation_axis(axis_idx, nullptr); WM_gizmo_set_matrix_location(axis, twmat[3]); switch (axis_idx) { @@ -1841,7 +1841,7 @@ static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup, const float scale[3], const bool ignore_hidden) { - GizmoGroup *ggd = gzgroup->customdata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); MAN_ITER_AXES_BEGIN (axis, axis_idx) { if (ignore_hidden && axis->flag & WM_GIZMO_HIDDEN) { @@ -1863,12 +1863,12 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup) } } - GizmoGroup *ggd = gzgroup->customdata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); Scene *scene = CTX_data_scene(C); ScrArea *area = CTX_wm_area(C); - View3D *v3d = area->spacedata.first; - RegionView3D *rv3d = region->regiondata; - struct TransformBounds tbounds; + View3D *v3d = static_cast(area->spacedata.first); + RegionView3D *rv3d = static_cast(region->regiondata); + TransformBounds tbounds; if (ggd->use_twtype_refresh) { ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init; @@ -1881,23 +1881,21 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup) const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, ggd->twtype_init); /* skip, we don't draw anything anyway */ - if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(C, - &(struct TransformCalcParams){ - .use_only_center = true, - .orientation_index = orient_index + 1, - }, - &tbounds) == 0))) { + TransformCalcParams calc_params{}; + calc_params.use_only_center = true; + calc_params.orientation_index = orient_index + 1; + if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0))) { return; } gizmo_prepare_mat(C, rv3d, &tbounds); - gizmogroup_refresh_from_matrix(gzgroup, rv3d->twmat, NULL, false); + gizmogroup_refresh_from_matrix(gzgroup, rv3d->twmat, nullptr, false); } static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, - struct wmMsgBus *mbus) + wmMsgBus *mbus) { Scene *scene = CTX_data_scene(C); bScreen *screen = CTX_wm_screen(C); @@ -1917,11 +1915,11 @@ static void gizmogroup_hide_all(GizmoGroup *ggd) static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoGroup *ggd = gzgroup->customdata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); // ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - // View3D *v3d = area->spacedata.first; - RegionView3D *rv3d = region->regiondata; + // View3D *v3d =static_cast< View3D *> (area->spacedata.first); + RegionView3D *rv3d = static_cast(region->regiondata); float viewinv_m3[3][3]; copy_m3_m4(viewinv_m3, rv3d->viewinv); float idot[3]; @@ -2003,10 +2001,10 @@ static void gizmo_3d_draw_invoke(wmGizmoGroup *gzgroup, const int axis_idx_active, const float mval[2]) { - GizmoGroup *ggd = gzgroup->customdata; - const RegionView3D *rv3d = region->regiondata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); + const RegionView3D *rv3d = static_cast(region->regiondata); - struct wmGizmo *axis_active = ggd->gizmos[axis_idx_active]; + wmGizmo *axis_active = ggd->gizmos[axis_idx_active]; const short axis_active_type = gizmo_get_axis_type(axis_idx_active); if (axis_active_type == MAN_AXES_ROTATE) { @@ -2046,7 +2044,7 @@ static void gizmo_3d_draw_invoke(wmGizmoGroup *gzgroup, if (axis->flag & WM_GIZMO_HIDDEN) { continue; } - gizmo_refresh_from_matrix(axis, axis_idx, ggd->twtype, rv3d->twmat, NULL); + gizmo_refresh_from_matrix(axis, axis_idx, ggd->twtype, rv3d->twmat, nullptr); if (ELEM(axis_idx, MAN_AXIS_TRANS_C, MAN_AXIS_SCALE_C, MAN_AXIS_ROT_C, MAN_AXIS_ROT_T)) { WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]); @@ -2072,10 +2070,11 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C, wmGizmo *gz, const wmEvent *event) { - GizmoGroup *ggd = gzgroup->customdata; + GizmoGroup *ggd = static_cast(gzgroup->customdata); const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &gz); - gizmo_3d_draw_invoke(gzgroup, CTX_wm_region(C), axis_idx, (float[2]){UNPACK2(event->mval)}); + const float mval[2] = {float(event->mval[0]), float(event->mval[1])}; + gizmo_3d_draw_invoke(gzgroup, CTX_wm_region(C), axis_idx, mval); /* Support gizmo specific orientation. */ if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) { @@ -2147,11 +2146,10 @@ static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d) return true; } -static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C, - struct wmGizmoGroupType *UNUSED(gzgt)) +static bool WIDGETGROUP_gizmo_poll_context(const bContext *C, wmGizmoGroupType * /*gzgt*/) { ScrArea *area = CTX_wm_area(C); - View3D *v3d = area->spacedata.first; + View3D *v3d = static_cast(area->spacedata.first); if (!WIDGETGROUP_gizmo_poll_generic(v3d)) { return false; } @@ -2172,14 +2170,14 @@ static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C, return true; } -static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt) +static bool WIDGETGROUP_gizmo_poll_tool(const bContext *C, wmGizmoGroupType *gzgt) { if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) { return false; } ScrArea *area = CTX_wm_area(C); - View3D *v3d = area->spacedata.first; + View3D *v3d = static_cast(area->spacedata.first); if (!WIDGETGROUP_gizmo_poll_generic(v3d)) { return false; } @@ -2218,7 +2216,7 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt) {V3D_GIZMO_SHOW_OBJECT_ROTATE, "ROTATE", 0, "Rotate", ""}, {V3D_GIZMO_SHOW_OBJECT_SCALE, "SCALE", 0, "Scale", ""}, {0, "NONE", 0, "None", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; RNA_def_enum(gzgt->srna, "drag_action", @@ -2278,12 +2276,12 @@ static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzg return true; } -static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) +static void WIDGETGROUP_xform_cage_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup) { - struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), - __func__); + XFormCageWidgetGroup *xgzgroup = static_cast( + MEM_mallocN(sizeof(XFormCageWidgetGroup), __func__)); const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true); - xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL); + xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, nullptr); wmGizmo *gz = xgzgroup->gizmo; RNA_enum_set( @@ -2299,16 +2297,16 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup PointerRNA *ptr; /* assign operator */ - PropertyRNA *prop_release_confirm = NULL; - PropertyRNA *prop_constraint_axis = NULL; + PropertyRNA *prop_release_confirm = nullptr; + PropertyRNA *prop_constraint_axis = nullptr; int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { for (int z = 0; z < 3; z++) { const bool constraint[3] = {x != 1, y != 1, z != 1}; - ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL); - if (prop_release_confirm == NULL) { + ptr = WM_gizmo_operator_set(gz, i, ot_resize, nullptr); + if (prop_release_confirm == nullptr) { prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis"); } @@ -2324,22 +2322,20 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *region = CTX_wm_region(C); - RegionView3D *rv3d = region->regiondata; + RegionView3D *rv3d = static_cast(region->regiondata); Scene *scene = CTX_data_scene(C); - struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata; + XFormCageWidgetGroup *xgzgroup = static_cast(gzgroup->customdata); wmGizmo *gz = xgzgroup->gizmo; - struct TransformBounds tbounds; + TransformBounds tbounds; const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, SCE_ORIENT_SCALE); - if ((ED_transform_calc_gizmo_stats(C, - &(struct TransformCalcParams){ - .use_local_axis = true, - .orientation_index = orient_index + 1, - }, - &tbounds) == 0) || + TransformCalcParams calc_params{}; + calc_params.use_local_axis = true; + calc_params.orientation_index = orient_index + 1; + if ((ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) || equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) { WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } @@ -2368,18 +2364,18 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgr float matrix_offset_global[4][4]; mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset); - PropertyRNA *prop_center_override = NULL; + PropertyRNA *prop_center_override = nullptr; float center[3]; float center_global[3]; int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z; for (int x = 0; x < 3; x++) { - center[0] = (float)(1 - x) * dims[0]; + center[0] = float(1 - x) * dims[0]; for (int y = 0; y < 3; y++) { - center[1] = (float)(1 - y) * dims[1]; + center[1] = float(1 - y) * dims[1]; for (int z = 0; z < 3; z++) { - center[2] = (float)(1 - z) * dims[2]; - struct wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i); - if (prop_center_override == NULL) { + center[2] = float(1 - z) * dims[2]; + wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i); + if (prop_center_override == nullptr) { prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override"); } mul_v3_m4v3(center_global, matrix_offset_global, center); @@ -2396,7 +2392,7 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgr static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, - struct wmMsgBus *mbus) + wmMsgBus *mbus) { Scene *scene = CTX_data_scene(C); bScreen *screen = CTX_wm_screen(C); @@ -2407,7 +2403,7 @@ static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C, static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata; + XFormCageWidgetGroup *xgzgroup = static_cast(gzgroup->customdata); RegionView3D *rv3d = CTX_wm_region_view3d(C); { @@ -2477,10 +2473,10 @@ static bool WIDGETGROUP_xform_shear_poll(const bContext *C, wmGizmoGroupType *gz return true; } -static void WIDGETGROUP_xform_shear_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) +static void WIDGETGROUP_xform_shear_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup) { - struct XFormShearWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormShearWidgetGroup), - __func__); + XFormShearWidgetGroup *xgzgroup = static_cast( + MEM_mallocN(sizeof(XFormShearWidgetGroup), __func__)); const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true); @@ -2491,26 +2487,26 @@ static void WIDGETGROUP_xform_shear_setup(const bContext *UNUSED(C), wmGizmoGrou for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { - wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr); RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX); const int i_ortho_a = (i + j + 1) % 3; const int i_ortho_b = (i + (1 - j) + 1) % 3; interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f); gz->color[3] = 0.5f; - PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL); + PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr); RNA_boolean_set(ptr, "release_confirm", 1); xgzgroup->gizmo[i][j] = gz; } } for (int i = 0; i < 4; i++) { - wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr); RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX); RNA_enum_set(gz->ptr, "draw_options", 0); /* No stem. */ copy_v3_fl(gz->color, 1.0f); gz->color[3] = 0.5f; WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true); - PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL); + PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr); RNA_boolean_set(ptr, "release_confirm", 1); xgzgroup->gizmo_view[i] = gz; @@ -2529,10 +2525,10 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg { Scene *scene = CTX_data_scene(C); ARegion *region = CTX_wm_region(C); - RegionView3D *rv3d = region->regiondata; + RegionView3D *rv3d = static_cast(region->regiondata); - struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata; - struct TransformBounds tbounds; + XFormShearWidgetGroup *xgzgroup = static_cast(gzgroup->customdata); + TransformBounds tbounds; /* Needed to test view orientation changes. */ copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv); @@ -2541,12 +2537,10 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg scene, SCE_ORIENT_ROTATE); const int orient_index = BKE_scene_orientation_slot_get_index(orient_slot); - if (ED_transform_calc_gizmo_stats(C, - &(struct TransformCalcParams){ - .use_local_axis = false, - .orientation_index = orient_index + 1, - }, - &tbounds) == 0) { + TransformCalcParams calc_params{}; + calc_params.use_local_axis = false; + calc_params.orientation_index = orient_index + 1; + if (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { wmGizmo *gz = xgzgroup->gizmo[i][j]; @@ -2593,7 +2587,7 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C, wmGizmoGroup *gzgroup, - struct wmMsgBus *mbus) + wmMsgBus *mbus) { Scene *scene = CTX_data_scene(C); bScreen *screen = CTX_wm_screen(C); @@ -2605,7 +2599,7 @@ static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C, static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata; + XFormShearWidgetGroup *xgzgroup = static_cast(gzgroup->customdata); RegionView3D *rv3d = CTX_wm_region_view3d(C); { Scene *scene = CTX_data_scene(C); @@ -2708,14 +2702,14 @@ static wmGizmoGroup *gizmogroup_xform_find(TransInfo *t) } } - return NULL; + return nullptr; } void transform_gizmo_3d_model_from_constraint_and_mode_init(TransInfo *t) { wmGizmo *gizmo_modal_current = t->region && t->region->gizmo_map ? WM_gizmomap_get_modal(t->region->gizmo_map) : - NULL; + nullptr; if (!gizmo_modal_current || !ELEM(gizmo_modal_current->parent_gzgroup->type, g_GGT_xform_gizmo, g_GGT_xform_gizmo_context)) { @@ -2730,13 +2724,13 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t) } wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t); - if (gzgroup_xform == NULL) { + if (gzgroup_xform == nullptr) { return; } int axis_idx = -1; if (t->mode == TFM_TRACKBALL) { - axis_idx = MAN_AXIS_ROT_T; + /* Pass. Do not display gizmo. */ } else if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) { const int axis_map[3][7] = { @@ -2781,27 +2775,29 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t) wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map); if (axis_idx != -1) { - RegionView3D *rv3d = t->region->regiondata; - bool update_orientation = !(equals_v3v3(rv3d->twmat[0], t->spacemtx[0]) && - equals_v3v3(rv3d->twmat[1], t->spacemtx[1]) && - equals_v3v3(rv3d->twmat[2], t->spacemtx[2])); + RegionView3D *rv3d = static_cast(t->region->regiondata); + float(*mat_cmp)[3] = t->orient[t->orient_curr != O_DEFAULT ? t->orient_curr : O_SCENE].matrix; - GizmoGroup *ggd = gzgroup_xform->customdata; + bool update_orientation = !(equals_v3v3(rv3d->twmat[0], mat_cmp[0]) && + equals_v3v3(rv3d->twmat[1], mat_cmp[1]) && + equals_v3v3(rv3d->twmat[2], mat_cmp[2])); + + GizmoGroup *ggd = static_cast(gzgroup_xform->customdata); wmGizmo *gizmo_expected = ggd->gizmos[axis_idx]; if (update_orientation || gizmo_modal_current != gizmo_expected) { if (update_orientation) { - copy_m4_m3(rv3d->twmat, t->spacemtx); + copy_m4_m3(rv3d->twmat, mat_cmp); copy_v3_v3(rv3d->twmat[3], t->center_global); } - wmEvent event = {NULL}; + wmEvent event = {nullptr}; /* Set the initial mouse value. Used for rotation gizmos. */ copy_v2_v2_int(event.mval, t->mouse.imval); /* We need to update the position of the gizmo before invoking otherwise * #wmGizmo::scale_final could be calculated wrong. */ - gizmo_refresh_from_matrix(gizmo_expected, axis_idx, ggd->twtype, rv3d->twmat, NULL); + gizmo_refresh_from_matrix(gizmo_expected, axis_idx, ggd->twtype, rv3d->twmat, nullptr); BLI_assert_msg(!gizmo_modal_current || gizmo_modal_current->highlight_part == 0, "Avoid changing the highlight part"); @@ -2811,7 +2807,7 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t) } } else if (gizmo_modal_current) { - WM_gizmo_modal_set_while_modal(t->region->gizmo_map, t->context, NULL, NULL); + WM_gizmo_modal_set_while_modal(t->region->gizmo_map, t->context, nullptr, nullptr); } } @@ -2822,11 +2818,11 @@ void transform_gizmo_3d_model_from_constraint_and_mode_restore(TransInfo *t) } wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t); - if (gzgroup_xform == NULL) { + if (gzgroup_xform == nullptr) { return; } - GizmoGroup *ggd = gzgroup_xform->customdata; + GizmoGroup *ggd = static_cast(gzgroup_xform->customdata); /* #wmGizmoGroup::draw_prepare will handle the rest. */ MAN_ITER_AXES_BEGIN (axis, axis_idx) { diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c index 0271f8e1988..6eb5a5e3449 100644 --- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c +++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c @@ -261,7 +261,7 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup) copy_m3_m3(ggd->data.normal_mat3, tbounds_normal.axis); } - /* TODO(@campbellbarton): run second since this modifies the 3D view, it should not. */ + /* TODO(@ideasman42): run second since this modifies the 3D view, it should not. */ if (!ED_transform_calc_gizmo_stats(C, &(struct TransformCalcParams){ .orientation_index = ggd->data.orientation_index + 1, diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 38dbe742279..1295486550a 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -55,7 +55,7 @@ static void InputSpringFlip(TransInfo *t, MouseInput *mi, const double mval[2], InputSpring(t, mi, mval, output); /* flip scale */ - /* values can become really big when zoomed in so use longs T26598. */ + /* values can become really big when zoomed in so use longs #26598. */ if (((int64_t)((int)mi->center[0] - mval[0]) * (int64_t)((int)mi->center[0] - mi->imval[0]) + (int64_t)((int)mi->center[1] - mval[1]) * (int64_t)((int)mi->center[1] - mi->imval[1])) < 0) { diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index d76dba63262..4014fae07b3 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -884,7 +884,7 @@ void headerResize(TransInfo *t, const float vec[3], char *str, const int str_siz /** * \a smat is reference matrix only. * - * \note this is a tricky area, before making changes see: T29633, T42444 + * \note this is a tricky area, before making changes see: #29633, #42444 */ static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float size[3]) { @@ -1041,7 +1041,7 @@ void ElementResize(const TransInfo *t, if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) { if (t->options & CTX_POSE_BONE) { /* Without this, the resulting location of scaled bones aren't correct, - * especially noticeable scaling root or disconnected bones around the cursor, see T92515. */ + * especially noticeable scaling root or disconnected bones around the cursor, see #92515. */ mul_mat3_m4_v3(tc->poseobj->object_to_world, vec); } mul_m3_v3(td->smtx, vec); diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c index a48f84ef0bc..918ba6bd108 100644 --- a/source/blender/editors/transform/transform_mode_bend.c +++ b/source/blender/editors/transform/transform_mode_bend.c @@ -262,7 +262,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2])) +values.scale * shell_angle_to_dist((float)M_PI_2 + values.angle)); } - /* TODO(@campbellbarton): xform, compensate object center. */ + /* TODO(@ideasman42): xform, compensate object center. */ FOREACH_TRANS_DATA_CONTAINER (t, tc) { float warp_sta_local[3]; diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 3fcb56944d7..f54624c1a1b 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -429,7 +429,7 @@ static void calcEdgeSlide_mval_range(TransInfo *t, continue; } - /* This test is only relevant if object is not wire-drawn! See T32068. */ + /* This test is only relevant if object is not wire-drawn! See #32068. */ bool is_visible = !use_occlude_geometry || BMBVH_EdgeVisible(bmbvh, e, t->depsgraph, region, v3d, tc->obedit); @@ -617,7 +617,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo * which calculates the direction to slide based on clever checks. * * otherwise we simply use 'e_dir' as an edge-rail. - * (which is better when the attached edge is a boundary, see: T40422) + * (which is better when the attached edge is a boundary, see: #40422) */ #define EDGESLIDE_VERT_IS_INNER(v, e_dir) \ ((BM_edge_is_boundary(e_dir) == false) && (BM_vert_edge_count_nonwire(v) == 2)) @@ -717,7 +717,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo BMVert *v_prev; BMEdge *e_prev; - /* XXX, 'sv' will initialize multiple times, this is suspicious. see T34024. */ + /* XXX, 'sv' will initialize multiple times, this is suspicious. see #34024. */ BLI_assert(v != NULL); BLI_assert(sv_table[BM_elem_index_get(v)] != INDEX_INVALID); sv = SV_FROM_VERT(v); @@ -1207,7 +1207,7 @@ void drawEdgeSlide(TransInfo *t) immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); immBegin(GPU_PRIM_LINES, sld->totsv * 2); - /* TODO(@campbellbarton): Loop over all verts. */ + /* TODO(@ideasman42): Loop over all verts. */ sv = sld->sv; for (i = 0; i < sld->totsv; i++, sv++) { float a[3], b[3]; diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index bf9fba2b1e7..5a42edb9ad4 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -70,7 +70,7 @@ static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]) /* Use 'invalid' dist when `center == p1` (after projecting), * in this case scale will _never_ move the point in relation to the center, - * so it makes no sense to take it into account when scaling. see: T46503 */ + * so it makes no sense to take it into account when scaling. see: #46503 */ return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID; } @@ -96,7 +96,7 @@ static void constrain_scale_to_boundary(const float numerator, float *scale) { /* It's possible the numerator or denominator can be very close to zero due to so-called - * "catastrophic cancellation". See T102923 for an example. We use epsilon tests here to + * "catastrophic cancellation". See #102923 for an example. We use epsilon tests here to * distinguish between genuine negative coordinates versus coordinates that should be rounded off * to zero. */ const float epsilon = 0.25f / 65536.0f; /* i.e. Quarter of a texel on a 65536 x 65536 texture. */ diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index b171b227aa6..3ea18ef1152 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -500,7 +500,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) float pivot_local[3]; if (rotate_mode != TRANSLATE_ROTATE_OFF) { copy_v3_v3(pivot_local, t->tsnap.snap_source); - /* The pivot has to be in local-space (see T49494) */ + /* The pivot has to be in local-space (see #49494) */ if (tc->use_local_mat) { mul_m4_v3(tc->imat, pivot_local); } @@ -693,7 +693,7 @@ void initTranslation(TransInfo *t) copy_v3_fl(t->num.val_inc, t->snap[0]); t->num.unit_sys = t->scene->unit.system; if (t->spacetype == SPACE_VIEW3D) { - /* Handling units makes only sense in 3Dview... See T38877. */ + /* Handling units makes only sense in 3Dview... See #38877. */ t->num.unit_type[0] = B_UNIT_LENGTH; t->num.unit_type[1] = B_UNIT_LENGTH; t->num.unit_type[2] = B_UNIT_LENGTH; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 0da3bf4d85f..cca191b99af 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -420,10 +420,10 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event) t->context = NULL; /* XXX, workaround: active needs to be calculated before transforming, - * since we're not reading from 'td->center' in this case. see: T40241 */ + * since we're not reading from 'td->center' in this case. see: #40241 */ if (t->tsnap.source_operation == SCE_SNAP_SOURCE_ACTIVE) { /* In camera view, tsnap callback is not set - * (see #initSnappingMode() in transform_snap.c, and T40348). */ + * (see #initSnappingMode() in transform_snap.c, and #40348). */ if (t->tsnap.snap_source_fn && ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0)) { t->tsnap.snap_source_fn(t); } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 66fee01f864..0cf9d5fa309 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -526,7 +526,7 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene, if (ob) { if (ob->mode & OB_MODE_POSE) { /* Each bone moves on its own local axis, but to avoid confusion, - * use the active pones axis for display T33575, this works as expected on a single + * use the active pones axis for display #33575, this works as expected on a single * bone and users who select many bones will understand what's going on and what local * means when they start transforming. */ ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat); @@ -889,7 +889,7 @@ int getTransformOrientation_ex(const Scene *scene, * - Point the Z axis outwards (the same direction as the normals). * * \note Z points outwards - along the normal. - * take care making changes here, see: T38592, T43708 + * take care making changes here, see: #38592, #43708 */ /* be deterministic where possible and ensure v_pair[0] is active */ @@ -1197,7 +1197,7 @@ int getTransformOrientation_ex(const Scene *scene, /* align normal to edge direction (so normal is perpendicular to the plane). * 'ORIENTATION_EDGE' will do the other way around. - * This has to be done **after** applying obmat, see T45775! */ + * This has to be done **after** applying obmat, see #45775! */ project_v3_v3v3(tvec, normal, plane); sub_v3_v3(normal, tvec); } diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 425f97a23f4..50f6da7486d 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -699,10 +699,10 @@ static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t) if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) { /* In "Edit Strokes" mode, - * snap tool can perform snap to selected or active objects (see T49632) + * snap tool can perform snap to selected or active objects (see #49632) * TODO: perform self snap in gpencil_strokes. * - * When we're moving the origins, allow snapping onto our own geometry (see T69132). */ + * When we're moving the origins, allow snapping onto our own geometry (see #69132). */ return ret; } diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index a33f0bf6fca..7fa13180f67 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -162,7 +162,7 @@ struct SnapObjectContext { * * - When the return value is null the `BKE_editmesh_from_object(ob_eval)` should be used. * - In rare cases there is no evaluated mesh available and a null result doesn't imply an - * edit-mesh, so callers need to account for a null edit-mesh too, see: T96536. + * edit-mesh, so callers need to account for a null edit-mesh too, see: #96536. */ static ID *data_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide) { @@ -726,7 +726,7 @@ static bool raycastMesh(SnapObjectContext *sctx, } /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with - * very far away ray_start values (as returned in case of ortho view3d), see T50486, T38358. + * very far away ray_start values (as returned in case of ortho view3d), see #50486, #38358. */ if (len_diff > 400.0f) { /* Make temporary start point a bit away from bounding-box hit point. */ @@ -860,7 +860,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx, } /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with - * very far away ray_start values (as returned in case of ortho view3d), see T50486, T38358. + * very far away ray_start values (as returned in case of ortho view3d), see #50486, #38358. */ if (len_diff > 400.0f) { len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ @@ -1375,7 +1375,7 @@ static bool snap_bound_box_check_dist(const float min[3], float dist_px_sq) { /* In vertex and edges you need to get the pixel distance from ray to BoundBox, - * see: T46099, T46816 */ + * see: #46099, #46816 */ DistProjectedAABBPrecalc data_precalc; dist_squared_to_projected_aabb_precalc(&data_precalc, lpmat, win_size, mval); diff --git a/source/blender/editors/undo/ed_undo.cc b/source/blender/editors/undo/ed_undo.cc index 0b51fe24fc4..b4a42f9e1ea 100644 --- a/source/blender/editors/undo/ed_undo.cc +++ b/source/blender/editors/undo/ed_undo.cc @@ -121,7 +121,7 @@ void ED_undo_push(bContext *C, const char *str) } if (G.background) { /* Python developers may have explicitly created the undo stack in background mode, - * otherwise allow it to be nullptr, see: T60934. + * otherwise allow it to be nullptr, see: #60934. * Otherwise it must never be nullptr, even when undo is disabled. */ if (wm->undo_stack == nullptr) { return; @@ -265,7 +265,7 @@ static int ed_undo_step_direction(bContext *C, enum eUndoStepDir step, ReportLis CLOG_INFO(&LOG, 1, "direction=%s", (step == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO"); - /* TODO(@campbellbarton): undo_system: use undo system */ + /* TODO(@ideasman42): undo_system: use undo system */ /* grease pencil can be can be used in plenty of spaces, so check it first */ /* FIXME: This gpencil undo effectively only supports the one step undo/redo, undo based on name * or index is fully not implemented. @@ -428,7 +428,7 @@ bool ED_undo_is_valid(const bContext *C, const char *undoname) bool ED_undo_is_memfile_compatible(const bContext *C) { - /* Some modes don't co-exist with memfile undo, disable their use: T60593 + /* Some modes don't co-exist with memfile undo, disable their use: #60593 * (this matches 2.7x behavior). */ const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -511,7 +511,7 @@ static int ed_undo_exec(bContext *C, wmOperator *op) static int ed_undo_push_exec(bContext *C, wmOperator *op) { if (G.background) { - /* Exception for background mode, see: T60934. + /* Exception for background mode, see: #60934. * NOTE: since the undo stack isn't initialized on startup, background mode behavior * won't match regular usage, this is just for scripts to do explicit undo pushes. */ wmWindowManager *wm = CTX_wm_manager(C); @@ -546,7 +546,7 @@ static int ed_undo_redo_exec(bContext *C, wmOperator * /*op*/) return ret; } -/* Disable in background mode, we could support if it's useful, T60934. */ +/* Disable in background mode, we could support if it's useful, #60934. */ static bool ed_undo_is_init_poll(bContext *C) { @@ -680,7 +680,7 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op) if (WM_operator_repeat_check(C, op) && WM_operator_poll(C, op->type) && /* NOTE: undo/redo can't run if there are jobs active, * check for screen jobs only so jobs like material/texture/world preview - * (which copy their data), won't stop redo, see T29579], + * (which copy their data), won't stop redo, see #29579. * * NOTE: WM_operator_check_ui_enabled() jobs test _must_ stay in sync with this. */ (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY) == 0)) { diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index f06e99da3bd..66c3b9da74c 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -28,7 +28,7 @@ set(INC_SYS set(SRC ed_draw.c ed_transverts.c - ed_util.c + ed_util.cc ed_util_imbuf.c ed_util_ops.cc ed_viewer_path.cc diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c index 334516bfd6c..e91242cb9e6 100644 --- a/source/blender/editors/util/ed_transverts.c +++ b/source/blender/editors/util/ed_transverts.c @@ -164,7 +164,7 @@ static void set_mapped_co(void *vuserdata, int index, const float co[3], const f tv = &tv[BM_elem_index_get(eve)]; /* Be clever, get the closest vertex to the original, - * behaves most logically when the mirror modifier is used for eg T33051. */ + * behaves most logically when the mirror modifier is used for eg #33051. */ if ((tv->flag & TX_VERT_USE_MAPLOC) == 0) { /* first time */ copy_v3_v3(tv->maploc, co); diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.cc similarity index 84% rename from source/blender/editors/util/ed_util.c rename to source/blender/editors/util/ed_util.cc index 8bc4f79a9df..77e5be4e0dd 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.cc @@ -5,9 +5,9 @@ * \ingroup edutil */ -#include -#include -#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -59,7 +59,7 @@ void ED_editors_init_for_undo(Main *bmain) { - wmWindowManager *wm = bmain->wm.first; + wmWindowManager *wm = static_cast(bmain->wm.first); LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { Scene *scene = WM_window_get_active_scene(win); ViewLayer *view_layer = WM_window_get_active_view_layer(win); @@ -67,14 +67,14 @@ void ED_editors_init_for_undo(Main *bmain) Object *ob = BKE_view_layer_active_object_get(view_layer); if (ob && (ob->mode & OB_MODE_TEXTURE_PAINT)) { BKE_texpaint_slots_refresh_object(scene, ob); - ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + ED_paint_proj_mesh_data_check(scene, ob, nullptr, nullptr, nullptr, nullptr); } } } void ED_editors_init(bContext *C) { - struct Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); + Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); wmWindowManager *wm = CTX_wm_manager(C); @@ -92,12 +92,12 @@ void ED_editors_init(bContext *C) * e.g. linked objects we have to ensure that they are actually the * active object in this scene. */ Object *obact = CTX_data_active_object(C); - for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { int mode = ob->mode; if (mode == OB_MODE_OBJECT) { continue; } - if (BKE_object_has_mode_data(ob, mode)) { + if (BKE_object_has_mode_data(ob, eObjectMode(mode))) { /* For multi-edit mode we may already have mode data. */ continue; } @@ -113,25 +113,25 @@ void ED_editors_init(bContext *C) DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); } else if (mode & OB_MODE_ALL_PAINT_GPENCIL) { - ED_gpencil_toggle_brush_cursor(C, true, NULL); + ED_gpencil_toggle_brush_cursor(C, true, nullptr); } continue; } /* Reset object to Object mode, so that code below can properly re-switch it to its * previous mode if possible, re-creating its mode data, etc. */ - ID *ob_data = ob->data; + ID *ob_data = static_cast(ob->data); ob->mode = OB_MODE_OBJECT; DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); /* Object mode is enforced if there is no active object, or if the active object's type is * different. */ - if (obact == NULL || ob->type != obact->type) { + if (obact == nullptr || ob->type != obact->type) { continue; } /* Object mode is enforced for non-editable data (or their obdata). */ if (!BKE_id_is_editable(bmain, &ob->id) || - (ob_data != NULL && !BKE_id_is_editable(bmain, ob_data))) { + (ob_data != nullptr && !BKE_id_is_editable(bmain, ob_data))) { continue; } @@ -144,7 +144,7 @@ void ED_editors_init(bContext *C) /* Other edit/paint/etc. modes are only settable for objects visible in active scene currently. * Otherwise, they (and their obdata) may not be (fully) evaluated, which is mandatory for some * modes like Sculpt. - * Ref. T98225. */ + * Ref. #98225. */ if (!BKE_collection_has_object_recursive(scene->master_collection, ob) || !BKE_scene_has_object(scene, ob) || (ob->visibility_flag & OB_HIDE_VIEWPORT) != 0) { continue; @@ -178,9 +178,9 @@ void ED_editors_init(bContext *C) } } else { - /* TODO(@campbellbarton): avoid operator calls. */ + /* TODO(@ideasman42): avoid operator calls. */ if (obact == ob) { - ED_object_mode_set(C, mode); + ED_object_mode_set(C, eObjectMode(mode)); } } } @@ -193,7 +193,7 @@ void ED_editors_init(bContext *C) /* Enforce a full redraw for the first time areas/regions get drawn. Further region init/refresh * just triggers non-rebuild redraws (#RGN_DRAW_NO_REBUILD). Usually a full redraw would be * triggered by a `NC_WM | ND_FILEREAD` notifier, but if a startup script calls an operator that - * redraws the window, notifiers are not handled before the operator runs. See T98461. */ + * redraws the window, notifiers are not handled before the operator runs. See #98461. */ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { const bScreen *screen = WM_window_get_active_screen(win); @@ -216,12 +216,12 @@ void ED_editors_exit(Main *bmain, bool do_undo_system) /* Frees all edit-mode undo-steps. */ if (do_undo_system && G_MAIN->wm.first) { - wmWindowManager *wm = G_MAIN->wm.first; - /* normally we don't check for NULL undo stack, + wmWindowManager *wm = static_cast(G_MAIN->wm.first); + /* normally we don't check for null undo stack, * do here since it may run in different context. */ if (wm->undo_stack) { BKE_undosys_stack_destroy(wm->undo_stack); - wm->undo_stack = NULL; + wm->undo_stack = nullptr; } } @@ -235,8 +235,8 @@ void ED_editors_exit(Main *bmain, bool do_undo_system) * Python for example can do this, some callers to #ED_object_base_activate * don't handle modes either (doing so isn't always practical). * - * To reproduce the problem where stale data is used, see: T84920. */ - for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + * To reproduce the problem where stale data is used, see: #84920. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { if (ED_object_editmode_free_ex(bmain, ob)) { if (do_undo_system == false) { DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); @@ -245,8 +245,8 @@ void ED_editors_exit(Main *bmain, bool do_undo_system) } /* global in meshtools... */ - ED_mesh_mirror_spatial_table_end(NULL); - ED_mesh_mirror_topo_table_end(NULL); + ED_mesh_mirror_spatial_table_end(nullptr); + ED_mesh_mirror_topo_table_end(nullptr); } bool ED_editors_flush_edits_for_object_ex(Main *bmain, @@ -258,8 +258,8 @@ bool ED_editors_flush_edits_for_object_ex(Main *bmain, if (ob->mode & OB_MODE_SCULPT) { /* Don't allow flushing while in the middle of a stroke (frees data in use). * Auto-save prevents this from happening but scripts - * may cause a flush on saving: T53986. */ - if (ob->sculpt != NULL && ob->sculpt->cache == NULL) { + * may cause a flush on saving: #53986. */ + if (ob->sculpt != nullptr && ob->sculpt->cache == nullptr) { char *needs_flush_ptr = &ob->sculpt->needs_flush_to_id; if (check_needs_flush && (*needs_flush_ptr == 0)) { return false; @@ -283,8 +283,8 @@ bool ED_editors_flush_edits_for_object_ex(Main *bmain, } else if (ob->mode & OB_MODE_EDIT) { - char *needs_flush_ptr = BKE_object_data_editmode_flush_ptr_get(ob->data); - if (needs_flush_ptr != NULL) { + char *needs_flush_ptr = BKE_object_data_editmode_flush_ptr_get(static_cast(ob->data)); + if (needs_flush_ptr != nullptr) { if (check_needs_flush && (*needs_flush_ptr == 0)) { return false; } @@ -306,12 +306,11 @@ bool ED_editors_flush_edits_for_object(Main *bmain, Object *ob) bool ED_editors_flush_edits_ex(Main *bmain, bool for_render, bool check_needs_flush) { bool has_edited = false; - Object *ob; /* loop through all data to find edit mode or object mode, because during * exiting we might not have a context for edit object and multiple sculpt * objects can exist at the same time */ - for (ob = bmain->objects.first; ob; ob = ob->id.next) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { has_edited |= ED_editors_flush_edits_for_object_ex(bmain, ob, for_render, check_needs_flush); } @@ -357,7 +356,7 @@ void unpack_menu(bContext *C, const char *id_name, const char *abs_name, const char *folder, - struct PackedFile *pf) + PackedFile *pf) { Main *bmain = CTX_data_main(C); PointerRNA props_ptr; @@ -371,7 +370,7 @@ void unpack_menu(bContext *C, layout = UI_popup_menu_layout(pup); uiItemFullO_ptr( - layout, ot, IFACE_("Remove Pack"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + layout, ot, IFACE_("Remove Pack"), ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_REMOVE); RNA_string_set(&props_ptr, "id", id_name); @@ -384,7 +383,7 @@ void unpack_menu(bContext *C, switch (BKE_packedfile_compare_to_file(blendfile_path, local_name, pf)) { case PF_CMP_NOFILE: BLI_snprintf(line, sizeof(line), TIP_("Create %s"), local_name); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); @@ -392,7 +391,7 @@ void unpack_menu(bContext *C, case PF_CMP_EQUAL: BLI_snprintf(line, sizeof(line), TIP_("Use %s (identical)"), local_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); @@ -400,13 +399,13 @@ void unpack_menu(bContext *C, case PF_CMP_DIFFERS: BLI_snprintf(line, sizeof(line), TIP_("Use %s (differs)"), local_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); BLI_snprintf(line, sizeof(line), TIP_("Overwrite %s"), local_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); break; @@ -418,27 +417,27 @@ void unpack_menu(bContext *C, case PF_CMP_NOFILE: BLI_snprintf(line, sizeof(line), TIP_("Create %s"), abs_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_CMP_EQUAL: BLI_snprintf(line, sizeof(line), TIP_("Use %s (identical)"), abs_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_CMP_DIFFERS: BLI_snprintf(line, sizeof(line), TIP_("Use %s (differs)"), abs_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); BLI_snprintf(line, sizeof(line), TIP_("Overwrite %s"), abs_name); // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL); - uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; @@ -447,9 +446,7 @@ void unpack_menu(bContext *C, UI_popup_menu_end(C, pup); } -void ED_spacedata_id_remap(struct ScrArea *area, - struct SpaceLink *sl, - const struct IDRemapper *mappings) +void ED_spacedata_id_remap(ScrArea *area, SpaceLink *sl, const IDRemapper *mappings) { SpaceType *st = BKE_spacetype_from_id(sl->spacetype); if (st && st->id_remap) { @@ -457,15 +454,12 @@ void ED_spacedata_id_remap(struct ScrArea *area, } } -void ED_spacedata_id_remap_single(struct ScrArea *area, - struct SpaceLink *sl, - ID *old_id, - ID *new_id) +void ED_spacedata_id_remap_single(ScrArea *area, SpaceLink *sl, ID *old_id, ID *new_id) { SpaceType *st = BKE_spacetype_from_id(sl->spacetype); if (st && st->id_remap) { - struct IDRemapper *mappings = BKE_id_remapper_create(); + IDRemapper *mappings = BKE_id_remapper_create(); BKE_id_remapper_add(mappings, old_id, new_id); st->id_remap(area, sl, mappings); BKE_id_remapper_free(mappings); diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index b1c8fc42d08..bd1dacf0d61 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -431,7 +431,7 @@ void ED_imbuf_sample_draw(const bContext *C, ARegion *region, void *arg_info) immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor3fv(color); - /* TODO(@campbellbarton): lock to pixels. */ + /* TODO(@ideasman42): lock to pixels. */ rctf sample_rect_fl; BLI_rctf_init_pt_radius( &sample_rect_fl, diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 60cbc2a2df6..0e9f6dce6b9 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -455,7 +455,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) return true; case EVT_PADPERIOD: case EVT_PERIODKEY: - /* Force number-pad "." since some OS's/countries generate a comma char, see: T37992 */ + /* Force number-pad "." since some OS's/countries generate a comma char, see: #37992 */ ascii[0] = '.'; utf8_buf = ascii; break; @@ -594,7 +594,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) if (n->val_flag[idx] & NUM_INVERSE) { val = n->val[idx]; /* If we invert on radians when user is in degrees, - * you get unexpected results... See T53463. */ + * you get unexpected results... See #53463. */ if (!n->unit_use_radians && n->unit_type[idx] == B_UNIT_ROTATION) { val = RAD2DEG(val); } diff --git a/source/blender/editors/uvedit/uvedit_clipboard_graph_iso.cc b/source/blender/editors/uvedit/uvedit_clipboard_graph_iso.cc index e96ca132fe6..a9e6e8608b8 100644 --- a/source/blender/editors/uvedit/uvedit_clipboard_graph_iso.cc +++ b/source/blender/editors/uvedit/uvedit_clipboard_graph_iso.cc @@ -40,7 +40,7 @@ GraphISO::GraphISO(int n) * Better still is to use a different algorithm. See for example: * https://www.uni-ulm.de/fileadmin/website_uni_ulm/iui.inst.190/Mitarbeiter/toran/beatcs09.pdf */ - adjmat[i] = static_cast(MEM_callocN(n * sizeof *adjmat[i], __func__)); + adjmat[i] = static_cast(MEM_callocN(n * sizeof *adjmat[i], __func__)); } degree = nullptr; } @@ -69,7 +69,7 @@ void GraphISO::calculate_degrees() const if (degree) { return; } - degree = static_cast(MEM_mallocN(n * sizeof *degree, __func__)); + degree = static_cast(MEM_mallocN(n * sizeof *degree, __func__)); for (int v = 0; v < n; v++) { int row_count = 0; for (int w = 0; w < n; w++) { diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c index 6cb6e67cced..7517a526722 100644 --- a/source/blender/editors/uvedit/uvedit_rip.c +++ b/source/blender/editors/uvedit/uvedit_rip.c @@ -804,7 +804,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const * to detach the selection. * * We could also extract an edge loop from the boundary - * however in practice it's not that useful, see T78751. */ + * however in practice it's not that useful, see #78751. */ if (is_select_all_any) { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 5ed68690253..6897b171d8b 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -1343,8 +1343,8 @@ void uvedit_deselect_flush(const Scene *scene, BMEditMesh *em) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if ((!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) || - (!BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert))) { + if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) || + !BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert)) { BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); } } @@ -1392,7 +1392,7 @@ static BMLoop *bm_select_edgeloop_single_side_next(const Scene *scene, scene, l_step, v_from_next, offsets); } -/* TODO(@campbellbarton): support this in the BMesh API, as we have for clearing other types. */ +/* TODO(@ideasman42): support this in the BMesh API, as we have for clearing other types. */ static void bm_loop_tags_clear(BMesh *bm) { BMIter iter; @@ -1800,9 +1800,9 @@ static void uv_select_linked_multi(Scene *scene, BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */ - /* NOTE: we had 'use winding' so we don't consider overlapping islands as connected, see T44320 + /* NOTE: we had 'use winding' so we don't consider overlapping islands as connected, see #44320 * this made *every* projection split the island into front/back islands. - * Keep 'use_winding' to false, see: T50970. + * Keep 'use_winding' to false, see: #50970. * * Better solve this by having a delimit option for select-linked operator, * keeping island-select working as is. */ @@ -2283,14 +2283,14 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if ((uv_selectmode == UV_SELECT_EDGE) || (uv_selectmode == UV_SELECT_FACE)) { + if (ELEM(uv_selectmode, UV_SELECT_EDGE, UV_SELECT_FACE)) { /* Use UV edge selection to find vertices and edges that must be selected. */ bool es = BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, !es); BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); } /* Use UV vertex selection to find vertices and edges that must be selected. */ - else if ((uv_selectmode == UV_SELECT_VERTEX) || (uv_selectmode == UV_SELECT_ISLAND)) { + else if (ELEM(uv_selectmode, UV_SELECT_VERTEX, UV_SELECT_ISLAND)) { bool vs = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, !vs); BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); @@ -4302,7 +4302,7 @@ static bool overlap_tri_tri_uv_test(const float t1[3][2], * However, the `endpoint_bias` on segment intersections causes _exact_ overlapping * triangles not to be detected. * - * Resolve this problem at the small cost of calculating the triangle center, see T85508. */ + * Resolve this problem at the small cost of calculating the triangle center, see #85508. */ mid_v2_v2v2v2(vi, UNPACK3(t1)); if (isect_point_tri_v2(vi, UNPACK3(t2)) != 0) { return true; @@ -4402,7 +4402,7 @@ static int uv_select_overlap(bContext *C, const bool extend) BLI_polyfill_calc_arena(uv_verts, face_len, coords_sign, indices, arena); /* A beauty fill is necessary to remove degenerate triangles that may be produced from the - * above poly-fill (see T103913), otherwise the overlap tests can fail. */ + * above poly-fill (see #103913), otherwise the overlap tests can fail. */ BLI_polyfill_beautify(uv_verts, face_len, indices, arena, heap); for (int t = 0; t < tri_len; t++) { @@ -4564,7 +4564,7 @@ static float get_uv_vert_needle(const eUVSelectSimilar type, } } break; case UV_SSIM_PIN: - return (BM_ELEM_CD_GET_BOOL(loop, offsets.pin)) ? 1.0f : 0.0f; + return BM_ELEM_CD_GET_BOOL(loop, offsets.pin) ? 1.0f : 0.0f; default: BLI_assert_unreachable(); return false; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 356fbde0b72..4c5da3a0d57 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1839,7 +1839,7 @@ static StitchState *stitch_init(bContext *C, state->em = em; /* Workaround for sync-select & face-select mode which implies all selected faces are detached, - * for stitch this isn't useful behavior, see T86924. */ + * for stitch this isn't useful behavior, see #86924. */ const int selectmode_orig = scene->toolsettings->selectmode; scene->toolsettings->selectmode = SCE_SELECT_VERTEX; state->element_map = BM_uv_element_map_create(state->em->bm, scene, false, true, true, true); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index de98e3c48f7..050362d0c7f 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -2769,7 +2769,7 @@ static void uv_map_mirror(BMFace *efa, pole_count++; } } - if (pole_count == 0 || pole_count == efa->len) { + if (ELEM(pole_count, 0, efa->len)) { return; } for (int i = 0; i < efa->len; i++) { diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 53e25fb4a62..dc6e13b3d3a 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -50,7 +50,7 @@ NodeGroup *BlenderFileLoader::Load() // Adjust clipping start/end and set up a Z offset when the viewport preview // is used with the orthographic view. In this case, _re->clip_start is negative, // while Freestyle assumes that imported mesh data are in the camera coordinate - // system with the view point located at origin [bug T36009]. + // system with the view point located at origin [bug #36009]. _z_near = -0.001f; _z_offset = _re->clip_start + _z_near; _z_far = -_re->clip_end + _z_offset; diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp index 0701b1c4ef3..668f654159b 100644 --- a/source/blender/freestyle/intern/python/BPy_Convert.cpp +++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp @@ -376,7 +376,7 @@ PyObject *BPy_CurvePoint_from_CurvePoint(CurvePoint &cp) // member whose value is mutable upon iteration over different CurvePoints. // It is likely that such a mutable reference is passed to this function, // so that a new allocated CurvePoint instance is created here to avoid - // nasty bugs (cf. T41464). + // nasty bugs (cf. #41464). ((BPy_CurvePoint *)py_cp)->cp = new CurvePoint(cp); ((BPy_CurvePoint *)py_cp)->py_if0D.if0D = ((BPy_CurvePoint *)py_cp)->cp; ((BPy_CurvePoint *)py_cp)->py_if0D.borrowed = false; diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.cpp b/source/blender/freestyle/intern/view_map/BoxGrid.cpp index 4464aab6419..d2e760b6e6e 100644 --- a/source/blender/freestyle/intern/view_map/BoxGrid.cpp +++ b/source/blender/freestyle/intern/view_map/BoxGrid.cpp @@ -120,7 +120,7 @@ void BoxGrid::assignCells(OccluderSource & /*source*/, // Now allocate the cell table and fill it with default (empty) cells _cells.resize(_cellsX * _cellsY); for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { - (*i) = NULL; + (*i) = nullptr; } // Identify cells that will be used, and set the dimensions for each @@ -182,7 +182,7 @@ void BoxGrid::reorganizeCells() { // Sort the occluders by shallowest point for (vector::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { - if (*i != NULL) { + if (*i != nullptr) { (*i)->indexPolygons(); } } diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp index c1afb6de881..488cbc92124 100644 --- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp +++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp @@ -175,7 +175,7 @@ void CulledOccluderSource::cullViewEdges(ViewMap &viewMap, bool extensiveFEdgeSe // Either we have run out of FEdges, or we already have the one edge we need to determine // visibility Cull all remaining edges. - while (!ELEM(fe, NULL, festart)) { + while (!ELEM(fe, nullptr, festart)) { fe->setIsInImage(false); fe = fe->nextEdge(); } @@ -237,7 +237,7 @@ void CulledOccluderSource::cullViewEdges(ViewMap &viewMap, bool extensiveFEdgeSe expandGridSpaceOccluderProscenium(fe); } fe = fe->nextEdge(); - } while (!ELEM(fe, NULL, festart)); + } while (!ELEM(fe, nullptr, festart)); } } diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp index bb4dbd17f70..fb3b6bb546d 100644 --- a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp +++ b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp @@ -117,7 +117,7 @@ void SphericalGrid::assignCells(OccluderSource & /*source*/, // Now allocate the cell table and fill it with default (empty) cells _cells.resize(_cellsX * _cellsY); for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { - (*i) = NULL; + (*i) = nullptr; } // Identify cells that will be used, and set the dimensions for each @@ -178,7 +178,7 @@ void SphericalGrid::reorganizeCells() { // Sort the occluders by shallowest point for (vector::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { - if (*i != NULL) { + if (*i != nullptr) { (*i)->indexPolygons(); } } diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp index 09432aa4ac7..c7e57a81408 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp @@ -822,7 +822,7 @@ void ViewEdge::UpdateFEdges() do { currentEdge->setViewEdge(this); currentEdge = currentEdge->nextEdge(); - } while (!ELEM(currentEdge, NULL, _FEdgeB)); + } while (!ELEM(currentEdge, nullptr, _FEdgeB)); // last one _FEdgeB->setViewEdge(this); } diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp index 9c2919b0ca8..183538ddd93 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp @@ -983,7 +983,7 @@ static void computeVeryFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon) wFace = nullptr; } else { - qi = computeVisibility(ioViewMap, fe, grid, epsilon, *ve, &wFace, NULL); + qi = computeVisibility(ioViewMap, fe, grid, epsilon, *ve, &wFace, nullptr); } // Store test results diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp index 3082988bd36..677029feb4c 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp @@ -644,7 +644,7 @@ WFace *WShape::MakeFace(vector &iVertexList, vector::iterator it; // compute the face normal (v1v2 ^ v1v3) - // Double precision numbers are used here to avoid truncation errors [T47705] + // Double precision numbers are used here to avoid truncation errors [#47705] Vec3r v1, v2, v3; it = iVertexList.begin(); v1 = (*it)->GetVertex(); diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt index e3c0c0c898d..6e0dec8f4f6 100644 --- a/source/blender/geometry/CMakeLists.txt +++ b/source/blender/geometry/CMakeLists.txt @@ -16,6 +16,7 @@ set(INC set(SRC intern/add_curves_on_mesh.cc + intern/curve_constraints.cc intern/fillet_curves.cc intern/mesh_merge_by_distance.cc intern/mesh_primitive_cuboid.cc @@ -32,6 +33,7 @@ set(SRC intern/uv_parametrizer.cc GEO_add_curves_on_mesh.hh + GEO_curve_constraints.hh GEO_fillet_curves.hh GEO_mesh_merge_by_distance.hh GEO_mesh_primitive_cuboid.hh diff --git a/source/blender/geometry/GEO_curve_constraints.hh b/source/blender/geometry/GEO_curve_constraints.hh new file mode 100644 index 00000000000..0cec5d3ebf2 --- /dev/null +++ b/source/blender/geometry/GEO_curve_constraints.hh @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BKE_curves.hh" + +namespace blender::geometry::curve_constraints { + +void compute_segment_lengths(OffsetIndices points_by_curve, + Span positions, + IndexMask curve_selection, + MutableSpan r_segment_lengths); + +void solve_length_constraints(OffsetIndices points_by_curve, + IndexMask curve_selection, + Span segment_lenghts, + MutableSpan positions); + +void solve_length_and_collision_constraints(OffsetIndices points_by_curve, + IndexMask curve_selection, + Span segment_lengths, + Span start_positions, + const Mesh &surface, + const bke::CurvesSurfaceTransforms &transforms, + MutableSpan positions); + +} // namespace blender::geometry::curve_constraints diff --git a/source/blender/geometry/intern/curve_constraints.cc b/source/blender/geometry/intern/curve_constraints.cc new file mode 100644 index 00000000000..e2f77ed54f0 --- /dev/null +++ b/source/blender/geometry/intern/curve_constraints.cc @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_math_matrix.hh" +#include "BLI_task.hh" + +#include "GEO_curve_constraints.hh" + +#include "BKE_bvhutils.h" + +/** + * The code below uses a prefix naming convention to indicate the coordinate space: + * `cu`: Local space of the curves object that is being edited. + * `su`: Local space of the surface object. + * `wo`: World space. + */ + +namespace blender::geometry::curve_constraints { + +void compute_segment_lengths(const OffsetIndices points_by_curve, + const Span positions, + const IndexMask curve_selection, + MutableSpan r_segment_lengths) +{ + BLI_assert(r_segment_lengths.size() == points_by_curve.total_size()); + + threading::parallel_for(curve_selection.index_range(), 256, [&](const IndexRange range) { + for (const int curve_i : curve_selection.slice(range)) { + const IndexRange points = points_by_curve[curve_i].drop_back(1); + for (const int point_i : points) { + const float3 &p1 = positions[point_i]; + const float3 &p2 = positions[point_i + 1]; + const float length = math::distance(p1, p2); + r_segment_lengths[point_i] = length; + } + } + }); +} + +void solve_length_constraints(const OffsetIndices points_by_curve, + const IndexMask curve_selection, + const Span segment_lenghts, + MutableSpan positions) +{ + BLI_assert(segment_lenghts.size() == points_by_curve.total_size()); + + threading::parallel_for(curve_selection.index_range(), 256, [&](const IndexRange range) { + for (const int curve_i : curve_selection.slice(range)) { + const IndexRange points = points_by_curve[curve_i].drop_back(1); + for (const int point_i : points) { + const float3 &p1 = positions[point_i]; + float3 &p2 = positions[point_i + 1]; + const float3 direction = math::normalize(p2 - p1); + const float goal_length = segment_lenghts[point_i]; + p2 = p1 + direction * goal_length; + } + } + }); +} + +void solve_length_and_collision_constraints(const OffsetIndices points_by_curve, + const IndexMask curve_selection, + const Span segment_lengths_cu, + const Span start_positions_cu, + const Mesh &surface, + const bke::CurvesSurfaceTransforms &transforms, + MutableSpan positions_cu) +{ + solve_length_constraints(points_by_curve, curve_selection, segment_lengths_cu, positions_cu); + + BVHTreeFromMesh surface_bvh; + BKE_bvhtree_from_mesh_get(&surface_bvh, &surface, BVHTREE_FROM_LOOPTRI, 2); + BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh); }); + + const float radius = 0.001f; + const int max_collisions = 5; + + threading::parallel_for(curve_selection.index_range(), 64, [&](const IndexRange range) { + for (const int curve_i : curve_selection.slice(range)) { + const IndexRange points = points_by_curve[curve_i]; + + /* Sometimes not all collisions can be handled. This happens relatively rarely, but if it + * happens it's better to just not to move the curve instead of going into the surface. */ + bool revert_curve = false; + for (const int point_i : points.drop_front(1)) { + const float goal_segment_length_cu = segment_lengths_cu[point_i - 1]; + const float3 &prev_pos_cu = positions_cu[point_i - 1]; + const float3 &start_pos_cu = start_positions_cu[point_i]; + + int used_iterations = 0; + for ([[maybe_unused]] const int iteration : IndexRange(max_collisions)) { + used_iterations++; + const float3 &old_pos_cu = positions_cu[point_i]; + if (start_pos_cu == old_pos_cu) { + /* The point did not move, done. */ + break; + } + + /* Check if the point moved through a surface. */ + const float3 start_pos_su = math::transform_point(transforms.curves_to_surface, + start_pos_cu); + const float3 old_pos_su = math::transform_point(transforms.curves_to_surface, + old_pos_cu); + const float3 pos_diff_su = old_pos_su - start_pos_su; + float max_ray_length_su; + const float3 ray_direction_su = math::normalize_and_get_length(pos_diff_su, + max_ray_length_su); + BVHTreeRayHit hit; + hit.index = -1; + hit.dist = max_ray_length_su + radius; + BLI_bvhtree_ray_cast(surface_bvh.tree, + start_pos_su, + ray_direction_su, + radius, + &hit, + surface_bvh.raycast_callback, + &surface_bvh); + if (hit.index == -1) { + break; + } + const float3 hit_pos_su = hit.co; + const float3 hit_normal_su = hit.no; + if (math::dot(hit_normal_su, ray_direction_su) > 0.0f) { + /* Moving from the inside to the outside is ok. */ + break; + } + + /* The point was moved through a surface. Now put it back on the correct side of the + * surface and slide it on the surface to keep the length the same. */ + + const float3 hit_pos_cu = math::transform_point(transforms.surface_to_curves, + hit_pos_su); + const float3 hit_normal_cu = math::normalize( + math::transform_direction(transforms.surface_to_curves_normal, hit_normal_su)); + + /* Slide on a plane that is slightly above the surface. */ + const float3 plane_pos_cu = hit_pos_cu + hit_normal_cu * radius; + const float3 plane_normal_cu = hit_normal_cu; + + /* Decompose the current segment into the part normal and tangent to the collision + * surface. */ + const float3 collided_segment_cu = plane_pos_cu - prev_pos_cu; + const float3 slide_normal_cu = plane_normal_cu * + math::dot(collided_segment_cu, plane_normal_cu); + const float3 slide_direction_cu = collided_segment_cu - slide_normal_cu; + + float slide_direction_length_cu; + const float3 normalized_slide_direction_cu = math::normalize_and_get_length( + slide_direction_cu, slide_direction_length_cu); + + /* Use pythagorian theorem to determine how far to slide. */ + const float slide_distance_cu = std::sqrt(pow2f(goal_segment_length_cu) - + math::length_squared(slide_normal_cu)) - + slide_direction_length_cu; + positions_cu[point_i] = plane_pos_cu + normalized_slide_direction_cu * slide_distance_cu; + } + if (used_iterations == max_collisions) { + revert_curve = true; + break; + } + } + if (revert_curve) { + positions_cu.slice(points).copy_from(start_positions_cu.slice(points)); + } + } + }); +} + +} // namespace blender::geometry::curve_constraints diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index cd97001bab6..61f37ca5fd7 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -353,7 +353,7 @@ static void p_triangle_angles( *r_a2 = angle_v3v3v3(v1, v2, v3); *r_a3 = angle_v3v3v3(v2, v3, v1); - /* Fix for degenerate geometry e.g. v1 = sum(v2 + v3). See T100874 */ + /* Fix for degenerate geometry e.g. v1 = sum(v2 + v3). See #100874 */ fix_large_angle(v1, v2, v3, r_a1, r_a2, r_a3); fix_large_angle(v2, v3, v1, r_a2, r_a3, r_a1); fix_large_angle(v3, v1, v2, r_a3, r_a1, r_a2); @@ -3259,7 +3259,7 @@ static float p_face_stretch(PFace *f) if (area <= 0.0f) { /* When a face is flipped, provide a large penalty. - * Add on a slight gradient to unflip the face, see also: T99781. */ + * Add on a slight gradient to unflip the face, see also: #99781. */ return 1e8f * (1.0f + p_edge_uv_length(e1) + p_edge_uv_length(e2) + p_edge_uv_length(e3)); } @@ -3871,7 +3871,7 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, if (nverts > 3) { /* Protect against (manifold) geometry which has a non-manifold triangulation. - * See T102543. */ + * See #102543. */ blender::Vector permute; permute.reserve(nverts); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c index ed94581b628..490efecdeb5 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c @@ -388,7 +388,7 @@ static void custom_range_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); uiLayoutSetActive(layout, - (!ELEM(mode, GP_TIME_MODE_FIX, GP_TIME_MODE_CHAIN)) && + !ELEM(mode, GP_TIME_MODE_FIX, GP_TIME_MODE_CHAIN) && RNA_boolean_get(ptr, "use_custom_frame_range")); col = uiLayoutColumn(layout, true); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index fe8621bb9fe..92070721816 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -2458,7 +2458,7 @@ static void lineart_object_load_single_instance(LineartData *ld, if ((!use_mesh) || use_mesh->edit_mesh) { /* If the object is being edited, then the mesh is not evaluated fully into the final * result, do not load them. This could be caused by incorrect evaluation order due to - * the way line art uses depsgraph.See T102612 for explanation of this workaround. */ + * the way line art uses depsgraph.See #102612 for explanation of this workaround. */ return; } } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 6804c63d4e4..2f345ec6a90 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -70,7 +70,7 @@ set(SRC intern/gpu_select_pick.c intern/gpu_select_sample_query.cc intern/gpu_shader.cc - intern/gpu_shader_builtin.c + intern/gpu_shader_builtin.cc intern/gpu_shader_create_info.cc intern/gpu_shader_dependency.cc intern/gpu_shader_interface.cc @@ -195,6 +195,7 @@ set(VULKAN_SRC vulkan/vk_fence.cc vulkan/vk_framebuffer.cc vulkan/vk_index_buffer.cc + vulkan/vk_memory.cc vulkan/vk_pixel_buffer.cc vulkan/vk_query.cc vulkan/vk_shader.cc @@ -211,6 +212,7 @@ set(VULKAN_SRC vulkan/vk_fence.hh vulkan/vk_framebuffer.hh vulkan/vk_index_buffer.hh + vulkan/vk_memory.hh vulkan/vk_pixel_buffer.hh vulkan/vk_query.hh vulkan/vk_shader.hh @@ -303,6 +305,10 @@ if(WITH_VULKAN_BACKEND) add_definitions(-DWITH_VULKAN_BACKEND) endif() +if(WITH_VULKAN_GUARDEDALLOC) + add_definitions(-DWITH_VULKAN_GUARDEDALLOC) +endif() + set(MSL_SRC shaders/metal/mtl_shader_defines.msl shaders/metal/mtl_shader_common.msl @@ -371,7 +377,6 @@ set(GLSL_SRC shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl shaders/gpu_shader_point_varying_color_varying_outline_aa_frag.glsl shaders/gpu_shader_point_varying_color_frag.glsl - shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl @@ -577,6 +582,7 @@ set(SRC_SHADER_CREATE_INFOS ../draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh ../draw/engines/eevee_next/shaders/infos/eevee_material_info.hh ../draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh + ../draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh ../draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh ../draw/engines/gpencil/shaders/infos/gpencil_info.hh ../draw/engines/gpencil/shaders/infos/gpencil_vfx_info.hh diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index 4935ced7f48..35d2d3f6e1a 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -4,8 +4,15 @@ /** \file * \ingroup gpu * - * GPU geometry batch - * Contains VAOs + VBOs + Shader representing a drawable entity. + * GPU geometry batch. + * + * Contains Vertex Buffers, Index Buffers, and Shader reference, altogether representing a drawable + * entity. It is meant to be used for drawing large (> 1000 vertices) reusable (drawn multiple + * times) model with complex data layout. In other words, it is meant for all cases where the + * immediate drawing module (imm) is inadequate. + * + * Vertex & Index Buffers can be owned by a batch. In such case they will be freed when the batch + * gets cleared or discarded. */ #pragma once @@ -60,7 +67,8 @@ extern "C" { /** * IMPORTANT: Do not allocate manually as the real struct is bigger (i.e: GLBatch). This is only - * the common and "public" part of the struct. Use the provided allocator. + * the common and "public" part of the struct. Use `GPU_batch_calloc()` and `GPU_batch_create()` + * instead. * TODO(fclem): Make the content of this struct hidden and expose getters/setters. */ typedef struct GPUBatch { @@ -80,75 +88,163 @@ typedef struct GPUBatch { struct GPUShader *shader; } GPUBatch; +/* -------------------------------------------------------------------- */ +/** \name Creation + * \{ */ + +/** + * Allocate a #GPUBatch with a cleared state. + * The returned #GPUBatch needs to be passed to `GPU_batch_init` before being usable. + */ GPUBatch *GPU_batch_calloc(void); -GPUBatch *GPU_batch_create_ex(GPUPrimType prim, - GPUVertBuf *vert, - GPUIndexBuf *elem, + +/** + * Creates a #GPUBatch with explicit buffer ownership. + */ +GPUBatch *GPU_batch_create_ex(GPUPrimType primitive_type, + GPUVertBuf *vertex_buf, + GPUIndexBuf *index_buf, eGPUBatchFlag owns_flag); +/** + * Creates a #GPUBatch without buffer ownership. + */ +#define GPU_batch_create(primitive_type, vertex_buf, index_buf) \ + GPU_batch_create_ex(primitive_type, vertex_buf, index_buf, (eGPUBatchFlag)0) + +/** + * Initialize a cleared #GPUBatch with explicit buffer ownership. + * A #GPUBatch is in cleared state if it was just allocated using `GPU_batch_calloc()` or cleared + * using `GPU_batch_clear()`. + */ void GPU_batch_init_ex(GPUBatch *batch, - GPUPrimType prim, - GPUVertBuf *vert, - GPUIndexBuf *elem, + GPUPrimType primitive_type, + GPUVertBuf *vertex_buf, + GPUIndexBuf *index_buf, eGPUBatchFlag owns_flag); /** + * Initialize a cleared #GPUBatch without buffer ownership. + * A #GPUBatch is in cleared state if it was just allocated using `GPU_batch_calloc()` or cleared + * using `GPU_batch_clear()`. + */ +#define GPU_batch_init(batch, primitive_type, vertex_buf, index_buf) \ + GPU_batch_init_ex(batch, primitive_type, vertex_buf, index_buf, (eGPUBatchFlag)0) + +/** + * DEPRECATED: It is easy to loose ownership with this. To be removed. * This will share the VBOs with the new batch. */ void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src); -#define GPU_batch_create(prim, verts, elem) \ - GPU_batch_create_ex(prim, verts, elem, (eGPUBatchFlag)0) -#define GPU_batch_init(batch, prim, verts, elem) \ - GPU_batch_init_ex(batch, prim, verts, elem, (eGPUBatchFlag)0) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Deletion + * \{ */ /** - * Same as discard but does not free. (does not call free callback). + * Clear a #GPUBatch without freeing its own memory. + * The #GPUBatch can then be reused using `GPU_batch_init()`. + * Discards all owned vertex and index buffers. */ -void GPU_batch_clear(GPUBatch *); +void GPU_batch_clear(GPUBatch *batch); + +#define GPU_BATCH_CLEAR_SAFE(batch) \ + do { \ + if (batch != NULL) { \ + GPU_batch_clear(batch); \ + memset(batch, 0, sizeof(*(batch))); \ + } \ + } while (0) /** - * \note Verts & elem are not discarded. + * Free a #GPUBatch object. + * Discards all owned vertex and index buffers. */ -void GPU_batch_discard(GPUBatch *); +void GPU_batch_discard(GPUBatch *batch); + +#define GPU_BATCH_DISCARD_SAFE(batch) \ + do { \ + if (batch != NULL) { \ + GPU_batch_discard(batch); \ + batch = NULL; \ + } \ + } while (0) + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Buffers Management + * \{ */ /** + * Add the given \a vertex_buf as vertex buffer to a #GPUBatch. + * \return the index of verts in the batch. + */ +int GPU_batch_vertbuf_add(GPUBatch *batch, GPUVertBuf *vertex_buf, bool own_vbo); + +/** + * Add the given \a vertex_buf as instanced vertex buffer to a #GPUBatch. + * \return the index of verts in the batch. + */ +int GPU_batch_instbuf_add(GPUBatch *batch, GPUVertBuf *vertex_buf, bool own_vbo); + +/** + * Set the first instanced vertex buffer of a #GPUBatch. * \note Override ONLY the first instance VBO (and free them if owned). */ -void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo); /* Instancing */ +void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *vertex_buf, bool own_vbo); + /** - * \note Override any previously assigned elem (and free it if owned). + * Set the index buffer of a #GPUBatch. + * \note Override any previously assigned index buffer (and free it if owned). */ -void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo); +void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *index_buf, bool own_ibo); -int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); /** - * Returns the index of verts in the batch. + * Returns true if the #GPUbatch has \a vertex_buf in its vertex buffer list. + * \note The search is only conducted on the non-instance rate vertex buffer list. */ -int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); -bool GPU_batch_vertbuf_has(GPUBatch *, GPUVertBuf *); - -#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false) +bool GPU_batch_vertbuf_has(GPUBatch *batch, GPUVertBuf *vertex_buf); /** - * Set resource id buffer to bind as instance attribute to workaround the lack of gl_BaseInstance. + * Set resource id buffer to bind as instance attribute to workaround the lack of gl_BaseInstance + * on some hardware / platform. + * \note Only to be used by draw manager. */ void GPU_batch_resource_id_buf_set(GPUBatch *batch, GPUStorageBuf *resource_id_buf); -void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader); -/** - * Bind program bound to IMM to the batch. +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shader Binding & Uniforms * - * XXX Use this with much care. Drawing with the #GPUBatch API is not compatible with IMM. - * DO NOT DRAW WITH THE BATCH BEFORE CALLING #immUnbindProgram. + * TODO(fclem): This whole section should be removed. See the other `TODO`s in this section. + * This is because we want to remove #GPUBatch.shader to avoid usage mistakes. + * Interacting directly with the #GPUShader provide a clearer interface and less error-prone. + * \{ */ + +/** + * Sets the shader to be drawn with this #GPUBatch. + * \note This need to be called first for the `GPU_batch_uniform_*` functions to work. */ -void GPU_batch_program_set_imm_shader(GPUBatch *batch); +/* TODO(fclem): These should be removed and replaced by `GPU_shader_bind()`. */ +void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader); void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id); void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig sh_cfg); +/** + * Bind program bound to IMM (immediate mode) to the #GPUBatch. + * + * XXX: Use this with much care. Drawing with the #GPUBatch API is not compatible with IMM. + * DO NOT DRAW WITH THE BATCH BEFORE CALLING #immUnbindProgram. + */ +void GPU_batch_program_set_imm_shader(GPUBatch *batch); -/* Will only work after setting the batch program. */ +/** + * Set uniform variables for the shader currently bound to the #GPUBatch. + */ /* TODO(fclem): These need to be replaced by GPU_shader_uniform_* with explicit shader. */ - #define GPU_batch_uniform_1i(batch, name, x) GPU_shader_uniform_1i((batch)->shader, name, x); #define GPU_batch_uniform_1b(batch, name, x) GPU_shader_uniform_1b((batch)->shader, name, x); #define GPU_batch_uniform_1f(batch, name, x) GPU_shader_uniform_1f((batch)->shader, name, x); @@ -167,103 +263,109 @@ void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, #define GPU_batch_uniform_mat4(batch, name, val) \ GPU_shader_uniform_mat4((batch)->shader, name, val); #define GPU_batch_uniformbuf_bind(batch, name, ubo) \ - GPU_uniformbuf_bind(ubo, GPU_shader_get_uniform_block_binding((batch)->shader, name)); + GPU_uniformbuf_bind(ubo, GPU_shader_get_ubo_binding((batch)->shader, name)); #define GPU_batch_texture_bind(batch, name, tex) \ - GPU_texture_bind(tex, GPU_shader_get_texture_binding((batch)->shader, name)); + GPU_texture_bind(tex, GPU_shader_get_sampler_binding((batch)->shader, name)); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shader Binding & Uniforms + * \{ */ /** - * Return indirect draw call parameters for this batch. - * NOTE: r_base_index is set to -1 if not using an index buffer. + * Draw the #GPUBatch with vertex count and instance count from its vertex buffers lengths. + * Ensures the associated shader is bound. TODO(fclem) remove this behavior. */ -void GPU_batch_draw_parameter_get( - GPUBatch *batch, int *r_v_count, int *r_v_first, int *r_base_index, int *r_i_count); - void GPU_batch_draw(GPUBatch *batch); -void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count); -/** - * Draw multiple instance of a batch without having any instance attributes. - */ -void GPU_batch_draw_instanced(GPUBatch *batch, int i_count); /** - * This does not bind/unbind shader and does not call GPU_matrix_bind(). + * Draw the #GPUBatch with vertex count and instance count from its vertex buffers lengths. + * Ensures the associated shader is bound. TODO(fclem) remove this behavior. + * + * A \a vertex_count of 0 will use the default number of vertex. + * The \a vertex_first sets the start of the instance-rate attributes. + * + * \note No out-of-bound access check is made on the vertex buffers since they are tricky to + * detect. Double check that the range of vertex has data or that the data isn't read by the + * shader. */ -void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_first, int i_count); +void GPU_batch_draw_range(GPUBatch *batch, int vertex_first, int vertex_count); /** - * Issue a draw call using GPU computed arguments. The argument are expected to be valid for the - * type of geometry drawn (index or non-indexed). + * Draw multiple instances of the #GPUBatch with custom instance range. + * Ensures the associated shader is bound. TODO(fclem) remove this behavior. + * + * An \a instance_count of 0 will use the default number of instances. + * The \a instance_first sets the start of the instance-rate attributes. + * + * \note this can be used even if the #GPUBatch contains no instance-rate attributes. + * \note No out-of-bound access check is made on the vertex buffers since they are tricky to + * detect. Double check that the range of vertex has data or that the data isn't read by the + * shader. + */ +void GPU_batch_draw_instance_range(GPUBatch *batch, int instance_first, int instance_count); + +/** + * Draw the #GPUBatch custom parameters. + * IMPORTANT: This does not bind/unbind shader and does not call GPU_matrix_bind(). + * + * A \a vertex_count of 0 will use the default number of vertex. + * An \a instance_count of 0 will use the default number of instances. + * + * \note No out-of-bound access check is made on the vertex buffers since they are tricky to + * detect. Double check that the range of vertex has data or that the data isn't read by the + * shader. + */ +void GPU_batch_draw_advanced( + GPUBatch *batch, int vertex_first, int vertex_count, int instance_first, int instance_count); + +/** + * Issue a single draw call using arguments sourced from a #GPUStorageBuf. + * The argument are expected to be valid for the type of geometry contained by this #GPUBatch + * (index or non-indexed). + * + * A `GPU_BARRIER_COMMAND` memory barrier is automatically added before the call. + * + * For more info see the GL documentation: + * https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDrawArraysIndirect.xhtml */ void GPU_batch_draw_indirect(GPUBatch *batch, GPUStorageBuf *indirect_buf, intptr_t offset); + +/** + * Issue \a count draw calls using arguments sourced from a #GPUStorageBuf. + * The \a stride (in bytes) control the spacing between each command description. + * The argument are expected to be valid for the type of geometry contained by this #GPUBatch + * (index or non-indexed). + * + * A `GPU_BARRIER_COMMAND` memory barrier is automatically added before the call. + * + * For more info see the GL documentation: + * https://registry.khronos.org/OpenGL-Refpages/gl4/html/glMultiDrawArraysIndirect.xhtml + */ void GPU_batch_multi_draw_indirect( GPUBatch *batch, GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride); -#if 0 /* future plans */ +/** + * Return indirect draw call parameters for this #GPUBatch. + * NOTE: \a r_base_index is set to -1 if not using an index buffer. + */ +void GPU_batch_draw_parameter_get(GPUBatch *batch, + int *r_vertex_count, + int *r_vertex_first, + int *r_base_index, + int *r_indices_count); -/* Can multiple batches share a #GPUVertBuf? Use ref count? */ +/** \} */ -/* We often need a batch with its own data, to be created and discarded together. */ -/* WithOwn variants reduce number of system allocations. */ - -typedef struct BatchWithOwnVertexBuffer { - GPUBatch batch; - GPUVertBuf verts; /* link batch.verts to this */ -} BatchWithOwnVertexBuffer; - -typedef struct BatchWithOwnElementList { - GPUBatch batch; - GPUIndexBuf elem; /* link batch.elem to this */ -} BatchWithOwnElementList; - -typedef struct BatchWithOwnVertexBufferAndElementList { - GPUBatch batch; - GPUIndexBuf elem; /* link batch.elem to this */ - GPUVertBuf verts; /* link batch.verts to this */ -} BatchWithOwnVertexBufferAndElementList; - -GPUBatch *create_BatchWithOwnVertexBuffer(GPUPrimType, GPUVertFormat *, uint v_len, GPUIndexBuf *); -GPUBatch *create_BatchWithOwnElementList(GPUPrimType, GPUVertBuf *, uint prim_len); -GPUBatch *create_BatchWithOwnVertexBufferAndElementList(GPUPrimType, - GPUVertFormat *, - uint v_len, - uint prim_len); -/* verts: shared, own */ -/* elem: none, shared, own */ -GPUBatch *create_BatchInGeneral(GPUPrimType, VertexBufferStuff, ElementListStuff); - -#endif /* future plans */ +/* -------------------------------------------------------------------- */ +/** \name Module init/exit + * \{ */ void gpu_batch_init(void); void gpu_batch_exit(void); -/* Macros */ - -#define GPU_BATCH_DISCARD_SAFE(batch) \ - do { \ - if (batch != NULL) { \ - GPU_batch_discard(batch); \ - batch = NULL; \ - } \ - } while (0) - -#define GPU_BATCH_CLEAR_SAFE(batch) \ - do { \ - if (batch != NULL) { \ - GPU_batch_clear(batch); \ - memset(batch, 0, sizeof(*(batch))); \ - } \ - } while (0) - -#define GPU_BATCH_DISCARD_ARRAY_SAFE(_batch_array, _len) \ - do { \ - if (_batch_array != NULL) { \ - BLI_assert(_len > 0); \ - for (int _i = 0; _i < _len; _i++) { \ - GPU_BATCH_DISCARD_SAFE(_batch_array[_i]); \ - } \ - MEM_freeN(_batch_array); \ - } \ - } while (0) +/** \} */ #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_index_buffer.h b/source/blender/gpu/GPU_index_buffer.h index e5fefda527d..9d152b01c8b 100644 --- a/source/blender/gpu/GPU_index_buffer.h +++ b/source/blender/gpu/GPU_index_buffer.h @@ -89,13 +89,11 @@ void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem, uint length); /** - * (Download and) return a pointer containing the data of an index buffer. + * (Download and) fill data with the contents of the index buffer. * - * Note that the returned pointer is still owned by the driver. To get an - * local copy, use `GPU_indexbuf_unmap` after calling `GPU_indexbuf_read`. + * NOTE: caller is responsible to reserve enough memory. */ -const uint32_t *GPU_indexbuf_read(GPUIndexBuf *elem); -uint32_t *GPU_indexbuf_unmap(const GPUIndexBuf *elem, const uint32_t *mapped_buffer); +void GPU_indexbuf_read(GPUIndexBuf *elem, uint32_t *data); void GPU_indexbuf_discard(GPUIndexBuf *elem); diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h index 2a9c4a89b2a..ed95bf8185f 100644 --- a/source/blender/gpu/GPU_matrix.h +++ b/source/blender/gpu/GPU_matrix.h @@ -95,7 +95,7 @@ struct GPUMatrixUnproject_Precalc { /** * Result of #projmat_dimensions_db. * Using double precision here is important as far clipping ranges - * can cause divide-by-zero when using float, see: T66937. + * can cause divide-by-zero when using float, see: #66937. */ struct { double xmin, xmax; diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 3cf64edaa6e..b9be4a5ec55 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -3,10 +3,14 @@ /** \file * \ingroup gpu + * + * A #GPUShader is a container for backend specific shader program. */ #pragma once +#include "GPU_shader_builtin.h" + #ifdef __cplusplus extern "C" { #endif @@ -18,6 +22,161 @@ typedef struct GPUShaderCreateInfo GPUShaderCreateInfo; /** Opaque type hiding #blender::gpu::Shader */ typedef struct GPUShader GPUShader; +/* Hardware limit is 16. Position attribute is always needed so we reduce to 15. + * This makes sure the GPUVertexFormat name buffer does not overflow. */ +#define GPU_MAX_ATTR 15 + +/* Determined by the maximum uniform buffer size divided by chunk size. */ +#define GPU_MAX_UNIFORM_ATTR 8 + +/* -------------------------------------------------------------------- */ +/** \name Creation + * \{ */ + +/** + * Create a shader using the given #GPUShaderCreateInfo. + * Can return a NULL pointer if compilation fails. + */ +GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info); + +/** + * Create a shader using a named #GPUShaderCreateInfo registered at startup. + * These are declared inside `*_info.hh` files using the `GPU_SHADER_CREATE_INFO()` macro. + * They are also expected to have been flagged using `do_static_compilation`. + * Can return a NULL pointer if compilation fails. + */ +GPUShader *GPU_shader_create_from_info_name(const char *info_name); + +/** + * Fetch a named #GPUShaderCreateInfo registered at startup. + * These are declared inside `*_info.hh` files using the `GPU_SHADER_CREATE_INFO()` macro. + * Can return a NULL pointer if no match is found. + */ +const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name); + +/** + * Error checking for user created shaders. + * \return true is create info is valid. + */ +bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128]); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free + * \{ */ + +void GPU_shader_free(GPUShader *shader); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Binding + * \{ */ + +/** + * Set the given shader as active shader for the active GPU context. + * It replaces any already bound shader. + * All following draw-calls and dispatches will use this shader. + * Uniform functions need to have the shader bound in order to work. (TODO: until we use + * glProgramUniform) + */ +void GPU_shader_bind(GPUShader *shader); + +/** + * Unbind the active shader. + * \note this is a no-op in release builds. But it make sense to actually do it in user land code + * to detect incorrect API usage. + */ +void GPU_shader_unbind(void); + +/** + * Return the currently bound shader to the active GPU context. + * \return NULL pointer if no shader is bound of if no context is active. + */ +GPUShader *GPU_shader_get_bound(void); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Debugging introspection API. + * \{ */ + +const char *GPU_shader_get_name(GPUShader *shader); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniform API. + * \{ */ + +/** + * Returns binding point location. + * Binding location are given to be set at shader compile time and immutable. + */ +int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name); +int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name); +int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name); + +/** + * Returns uniform location. + * If cached, it is faster than querying the interface for each uniform assignment. + */ +int GPU_shader_get_uniform(GPUShader *shader, const char *name); + +/** + * Sets a generic push constant (a.k.a. uniform). + * \a length and \a array_size should match the create info push_constant declaration. + */ +void GPU_shader_uniform_float_ex( + GPUShader *shader, int location, int length, int array_size, const float *value); +void GPU_shader_uniform_int_ex( + GPUShader *shader, int location, int length, int array_size, const int *value); + +/** + * Sets a generic push constant (a.k.a. uniform). + * \a length and \a array_size should match the create info push_constant declaration. + * These functions need to have the shader bound in order to work. (TODO: until we use + * glProgramUniform) + */ +void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value); +void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value); +void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value); +void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y); +void GPU_shader_uniform_3f(GPUShader *sh, const char *name, float x, float y, float z); +void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, float z, float w); +void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]); +void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]); +void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]); +void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2]); +void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]); +void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3]); +void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]); +void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Attribute API. + * + * Used to create #GPUVertexFormat from the shader's vertex input layout. + * \{ */ + +unsigned int GPU_shader_get_attribute_len(const GPUShader *shader); +int GPU_shader_get_attribute(const GPUShader *shader, const char *name); +bool GPU_shader_get_attribute_info(const GPUShader *shader, + int attr_location, + char r_name[256], + int *r_type); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Legacy API + * + * All of this section is deprecated and should be ported to use the API described above. + * \{ */ + typedef enum eGPUShaderTFBType { GPU_SHADER_TFB_NONE = 0, /* Transform feedback unsupported. */ GPU_SHADER_TFB_POINTS = 1, @@ -51,54 +210,6 @@ GPUShader *GPU_shader_create_ex(const char *vertcode, const char **tf_names, int tf_count, const char *shname); -GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info); -GPUShader *GPU_shader_create_from_info_name(const char *info_name); - -const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name); -bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128]); - -struct GPU_ShaderCreateFromArray_Params { - const char **vert, **geom, **frag, **defs; -}; -/** - * Use via #GPU_shader_create_from_arrays macro (avoids passing in param). - * - * Similar to #DRW_shader_create_with_lib with the ability to include libraries for each type of - * shader. - * - * It has the advantage that each item can be conditionally included - * without having to build the string inline, then free it. - * - * \param params: NULL terminated arrays of strings. - * - * Example: - * \code{.c} - * sh = GPU_shader_create_from_arrays({ - * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL}, - * .geom = (const char *[]){shader_geom_glsl, NULL}, - * .frag = (const char *[]){shader_frag_glsl, NULL}, - * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL}, - * }); - * \endcode - */ -struct GPUShader *GPU_shader_create_from_arrays_impl( - const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line); - -#define GPU_shader_create_from_arrays(...) \ - GPU_shader_create_from_arrays_impl( \ - &(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__, __func__, __LINE__) - -#define GPU_shader_create_from_arrays_named(name, ...) \ - GPU_shader_create_from_arrays_impl( \ - &(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__, name, 0) - -void GPU_shader_free(GPUShader *shader); - -void GPU_shader_bind(GPUShader *shader); -void GPU_shader_unbind(void); -GPUShader *GPU_shader_get_bound(void); - -const char *GPU_shader_get_name(GPUShader *shader); /** * Returns true if transform feedback was successfully enabled. @@ -109,6 +220,9 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader); /** DEPRECATED: Kept only because of BGL API. */ int GPU_shader_get_program(GPUShader *shader); +/** + * Indexed commonly used uniform name for faster lookup into the uniform cache. + */ typedef enum { GPU_UNIFORM_MODEL = 0, /* mat4 ModelMatrix */ GPU_UNIFORM_VIEW, /* mat4 ViewMatrix */ @@ -132,16 +246,19 @@ typedef enum { GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */ GPU_UNIFORM_RESOURCE_ID, /* int resourceId */ GPU_UNIFORM_SRGB_TRANSFORM, /* bool srgbTarget */ - - GPU_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ } GPUUniformBuiltin; +#define GPU_NUM_UNIFORMS (GPU_UNIFORM_SRGB_TRANSFORM + 1) +/** TODO: To be moved as private API. Not really used outside of gpu_matrix.cc and doesn't really + * offer a noticeable perf boost. */ +int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin); + +/** DEPRECATED: Use hardcoded buffer location instead. */ typedef enum { - /** Deprecated */ GPU_UNIFORM_BLOCK_VIEW = 0, /* viewBlock */ GPU_UNIFORM_BLOCK_MODEL, /* modelBlock */ GPU_UNIFORM_BLOCK_INFO, /* infoBlock */ - /** New ones */ + GPU_UNIFORM_BLOCK_DRW_VIEW, GPU_UNIFORM_BLOCK_DRW_MODEL, GPU_UNIFORM_BLOCK_DRW_INFOS, @@ -150,260 +267,13 @@ typedef enum { GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */ } GPUUniformBlockBuiltin; -typedef enum { - GPU_STORAGE_BUFFER_DEBUG_VERTS = 0, /* drw_debug_verts_buf */ - GPU_STORAGE_BUFFER_DEBUG_PRINT, /* drw_debug_print_buf */ - - GPU_NUM_STORAGE_BUFFERS, /* Special value, denotes number of builtin buffer blocks. */ -} GPUStorageBufferBuiltin; - -void GPU_shader_set_srgb_uniform(GPUShader *shader); - -int GPU_shader_get_uniform(GPUShader *shader, const char *name); -int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin); +/** DEPRECATED: Use hardcoded buffer location instead. */ int GPU_shader_get_builtin_block(GPUShader *shader, int builtin); -int GPU_shader_get_builtin_ssbo(GPUShader *shader, int builtin); + /** DEPRECATED: Kept only because of Python GPU API. */ int GPU_shader_get_uniform_block(GPUShader *shader, const char *name); -int GPU_shader_get_ssbo(GPUShader *shader, const char *name); -int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name); -int GPU_shader_get_texture_binding(GPUShader *shader, const char *name); - -void GPU_shader_uniform_vector( - GPUShader *shader, int location, int length, int arraysize, const float *value); -void GPU_shader_uniform_vector_int( - GPUShader *shader, int location, int length, int arraysize, const int *value); - -void GPU_shader_uniform_float(GPUShader *shader, int location, float value); -void GPU_shader_uniform_int(GPUShader *shader, int location, int value); - -void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value); -void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value); -void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value); -void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y); -void GPU_shader_uniform_3f(GPUShader *sh, const char *name, float x, float y, float z); -void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, float z, float w); -void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]); -void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]); -void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]); -void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2]); -void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]); -void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3]); -void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]); -void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]); - -unsigned int GPU_shader_get_attribute_len(const GPUShader *shader); -int GPU_shader_get_attribute(GPUShader *shader, const char *name); -bool GPU_shader_get_attribute_info(const GPUShader *shader, - int attr_location, - char r_name[256], - int *r_type); - -void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear); - -/* Builtin/Non-generated shaders */ -typedef enum eGPUBuiltinShader { - /* specialized drawing */ - GPU_SHADER_TEXT, - GPU_SHADER_KEYFRAME_SHAPE, - GPU_SHADER_SIMPLE_LIGHTING, - /** - * Draw an icon, leaving a semi-transparent rectangle on top of the icon. - */ - GPU_SHADER_ICON, - /** - * Take a 2D position and color for each vertex with linear interpolation in window space. - * - * \param color: in vec4 - * \param pos: in vec2 - */ - GPU_SHADER_2D_IMAGE_DESATURATE_COLOR, - GPU_SHADER_2D_IMAGE_RECT_COLOR, - GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR, - GPU_SHADER_2D_CHECKER, - GPU_SHADER_2D_DIAG_STRIPES, - /* for simple 3D drawing */ - /** - * Take a single color for all the vertices and a 3D position for each vertex. - * - * \param color: uniform vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_UNIFORM_COLOR, - GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR, - /** - * Take a 3D position and color for each vertex without color interpolation. - * - * \param color: in vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_FLAT_COLOR, - /** - * Take a 3D position and color for each vertex with perspective correct interpolation. - * - * \param color: in vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_SMOOTH_COLOR, - /** - * Take a single color for all the vertices and a 3D position for each vertex. - * Used for drawing wide lines. - * - * \param color: uniform vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, - GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR, - /** - * Take a 3D position and color for each vertex without color interpolation. - * Used for drawing wide lines. - * - * \param color: in vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_POLYLINE_FLAT_COLOR, - /** - * Take a 3D position and color for each vertex with perspective correct interpolation. - * Used for drawing wide lines. - * - * \param color: in vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR, - /** - * Take a 3D position for each vertex and output only depth. - * Used for drawing wide lines. - * - * \param pos: in vec3 - */ - GPU_SHADER_3D_DEPTH_ONLY, - /* basic image drawing */ - GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE, - GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE, - GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR, - /** - * Draw a texture in 3D. Take a 3D position and a 2D texture coordinate for each vertex. - * - * Exposed via Python-API for add-ons. - * - * \param image: uniform sampler2D - * \param texCoord: in vec2 - * \param pos: in vec3 - */ - GPU_SHADER_3D_IMAGE, - /** - * Take a 3D position and color for each vertex with linear interpolation in window space. - * - * \param color: uniform vec4 - * \param image: uniform sampler2D - * \param texCoord: in vec2 - * \param pos: in vec3 - */ - GPU_SHADER_3D_IMAGE_COLOR, - /* points */ - /** - * Draw round points with a constant size. - * Take a single color for all the vertices and a 2D position for each vertex. - * - * \param size: uniform float - * \param color: uniform vec4 - * \param pos: in vec2 - */ - GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, - /** - * Draw round points with a constant size and an outline. - * Take a single color for all the vertices and a 2D position for each vertex. - * - * \param size: uniform float - * \param outlineWidth: uniform float - * \param color: uniform vec4 - * \param outlineColor: uniform vec4 - * \param pos: in vec2 - */ - GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, - /** - * Draw round points with a hardcoded size. - * Take a single color for all the vertices and a 3D position for each vertex. - * - * \param color: uniform vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR, - /** - * Draw round points with a constant size. - * Take a single color for all the vertices and a 3D position for each vertex. - * - * \param size: uniform float - * \param color: uniform vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, - /** - * Draw round points with a constant size and an outline. - * Take a 3D position and a color for each vertex. - * - * \param size: in float - * \param color: in vec4 - * \param pos: in vec3 - */ - GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR, - /* lines */ - GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR, - /* grease pencil drawing */ - GPU_SHADER_GPENCIL_STROKE, - /* specialized for widget drawing */ - GPU_SHADER_2D_AREA_BORDERS, - GPU_SHADER_2D_WIDGET_BASE, - GPU_SHADER_2D_WIDGET_BASE_INST, - GPU_SHADER_2D_WIDGET_SHADOW, - GPU_SHADER_2D_NODELINK, - GPU_SHADER_2D_NODELINK_INST, -} eGPUBuiltinShader; -#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_2D_NODELINK_INST + 1) - -/** Support multiple configurations. */ -typedef enum eGPUShaderConfig { - GPU_SHADER_CFG_DEFAULT = 0, - GPU_SHADER_CFG_CLIPPED = 1, -} eGPUShaderConfig; -#define GPU_SHADER_CFG_LEN (GPU_SHADER_CFG_CLIPPED + 1) - -typedef struct GPUShaderConfigData { - const char *lib; - const char *def; -} GPUShaderConfigData; -/* gpu_shader.c */ - -extern const GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN]; - -GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, - eGPUShaderConfig sh_cfg); -GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader); - -void GPU_shader_free_builtin_shaders(void); - -/* Vertex attributes for shaders */ - -/* Hardware limit is 16. Position attribute is always needed so we reduce to 15. - * This makes sure the GPUVertexFormat name buffer does not overflow. */ -#define GPU_MAX_ATTR 15 - -/* Determined by the maximum uniform buffer size divided by chunk size. */ -#define GPU_MAX_UNIFORM_ATTR 8 - -typedef enum eGPUKeyframeShapes { - GPU_KEYFRAME_SHAPE_DIAMOND = (1 << 0), - GPU_KEYFRAME_SHAPE_CIRCLE = (1 << 1), - GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL = (1 << 2), - GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL = (1 << 3), - GPU_KEYFRAME_SHAPE_INNER_DOT = (1 << 4), - GPU_KEYFRAME_SHAPE_ARROW_END_MAX = (1 << 8), - GPU_KEYFRAME_SHAPE_ARROW_END_MIN = (1 << 9), - GPU_KEYFRAME_SHAPE_ARROW_END_MIXED = (1 << 10), -} eGPUKeyframeShapes; -#define GPU_KEYFRAME_SHAPE_SQUARE \ - (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) +/** \} */ #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_shader_builtin.h b/source/blender/gpu/GPU_shader_builtin.h new file mode 100644 index 00000000000..bd9fa9eb232 --- /dev/null +++ b/source/blender/gpu/GPU_shader_builtin.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + * + * Set of shaders used for interface drawing. + * + * 2D shaders are not expected to work in 3D. + * 3D shaders can work with 2D geometry and matrices. + * + * `INST` suffix means instance, which means the shader is build to leverage instancing + * capabilities to reduce the number of draw-calls. + * + * For full list of parameters, search for the the associated #ShaderCreateInfo. + * Example: `GPU_SHADER_ICON` is defined by `GPU_SHADER_CREATE_INFO(gpu_shader_icon)` + * Some parameters are builtins and are set automatically (ex: `ModelViewProjectionMatrix`). + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +struct GPUShader; + +typedef enum eGPUBuiltinShader { + /** Glyph drawing shader used by the BLF module. */ + GPU_SHADER_TEXT, + /** Draws keyframe markers. All markers shapes are supported through a single shader. */ + GPU_SHADER_KEYFRAME_SHAPE, + /** Draw solid mesh with a single distant light using a clamped simple dot product. */ + GPU_SHADER_SIMPLE_LIGHTING, + /** Draw an icon, leaving a semi-transparent rectangle on top of the icon. */ + GPU_SHADER_ICON, + /** Draw a texture with a uniform color multiplied. */ + GPU_SHADER_2D_IMAGE_RECT_COLOR, + /** Draw a texture with a desaturation factor. */ + GPU_SHADER_2D_IMAGE_DESATURATE_COLOR, + /** Draw a group of texture rectangle with an associated color multiplied. */ + GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR, + /** Draw a two color checker based on screen position (not UV coordinates). */ + GPU_SHADER_2D_CHECKER, + /** Draw diagonal stripes with two alternating colors. */ + GPU_SHADER_2D_DIAG_STRIPES, + /** Draw dashed lines with custom dash length and uniform color. */ + GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR, + /** Draw triangles / lines / points with only depth output. */ + GPU_SHADER_3D_DEPTH_ONLY, + /** Merge viewport overlay texture with the render output. */ + GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE, + GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE, + /** Merge viewport overlay texture with the render output. */ + GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR, + /** Used for drawing of annotations (former grease pencil). */ + GPU_SHADER_GPENCIL_STROKE, + /** Draw rounded area borders with silky smooth anti-aliasing without any over-draw. */ + GPU_SHADER_2D_AREA_BORDERS, + /** Multi usage widget shaders for drawing buttons and other UI elements. */ + GPU_SHADER_2D_WIDGET_BASE, + GPU_SHADER_2D_WIDGET_BASE_INST, + GPU_SHADER_2D_WIDGET_SHADOW, + /** Draw a node link given an input quadratic Bezier curve. */ + GPU_SHADER_2D_NODELINK, + GPU_SHADER_2D_NODELINK_INST, + + /** Draw round points with per vertex size and color. */ + GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR, + /** Draw round points with a uniform size. Disabling blending will disable AA. */ + GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, + GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, + /** Draw round points with a uniform size and an outline. Disabling blending will disable AA. */ + GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, + + /** Draw geometry with uniform color. Has an additional clip plane parameter. */ + GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR, + /** Draw wide lines with uniform color. Has an additional clip plane parameter. */ + GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR, + + /** + * ----------------------- Shaders exposed through pyGPU module ----------------------- + * + * Avoid breaking the interface of these shaders as they are used by addons. + * Polyline versions are used for drawing wide lines (> 1px width). + */ + + /** + * Take a 3D position and color for each vertex without color interpolation. + * + * \param color: in vec4 + * \param pos: in vec3 + */ + GPU_SHADER_3D_FLAT_COLOR, + GPU_SHADER_3D_POLYLINE_FLAT_COLOR, + /** + * Take a 3D position and color for each vertex with perspective correct interpolation. + * + * \param color: in vec4 + * \param pos: in vec3 + */ + GPU_SHADER_3D_SMOOTH_COLOR, + GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR, + /** + * Take a single color for all the vertices and a 3D position for each vertex. + * + * \param color: uniform vec4 + * \param pos: in vec3 + */ + GPU_SHADER_3D_UNIFORM_COLOR, + GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, + /** + * Draw a texture in 3D. Take a 3D position and a 2D texture coordinate for each vertex. + * + * \param image: uniform sampler2D + * \param texCoord: in vec2 + * \param pos: in vec3 + */ + GPU_SHADER_3D_IMAGE, + /** + * Take a 3D position and color for each vertex with linear interpolation in window space. + * + * \param color: uniform vec4 + * \param image: uniform sampler2D + * \param texCoord: in vec2 + * \param pos: in vec3 + */ + GPU_SHADER_3D_IMAGE_COLOR, +} eGPUBuiltinShader; +#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_3D_IMAGE_COLOR + 1) + +/** Support multiple configurations. */ +typedef enum eGPUShaderConfig { + GPU_SHADER_CFG_DEFAULT = 0, + GPU_SHADER_CFG_CLIPPED = 1, +} eGPUShaderConfig; +#define GPU_SHADER_CFG_LEN (GPU_SHADER_CFG_CLIPPED + 1) + +struct GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, + eGPUShaderConfig sh_cfg); +struct GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader); + +void GPU_shader_free_builtin_shaders(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/GPU_shader_shared.h b/source/blender/gpu/GPU_shader_shared.h index 4fb321ce502..66face85b07 100644 --- a/source/blender/gpu/GPU_shader_shared.h +++ b/source/blender/gpu/GPU_shader_shared.h @@ -11,6 +11,24 @@ typedef struct TestOutputRawData TestOutputRawData; #endif +/* NOTE: float3 has differing stride and alignment rules across different GPU backends. If 12 byte + * stride and alignment is essential, use `packed_float3` to avoid data read issues. This is + * required in the common use-case where a float3 and an int/float are paired together for optimal + * data transfer. */ + +enum eGPUKeyframeShapes { + GPU_KEYFRAME_SHAPE_DIAMOND = (1u << 0u), + GPU_KEYFRAME_SHAPE_CIRCLE = (1u << 1u), + GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL = (1u << 2u), + GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL = (1u << 3u), + GPU_KEYFRAME_SHAPE_INNER_DOT = (1u << 4u), + GPU_KEYFRAME_SHAPE_ARROW_END_MAX = (1u << 8u), + GPU_KEYFRAME_SHAPE_ARROW_END_MIN = (1u << 9u), + GPU_KEYFRAME_SHAPE_ARROW_END_MIXED = (1u << 10u), + GPU_KEYFRAME_SHAPE_SQUARE = (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | + GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL), +}; + struct NodeLinkData { float4 colors[3]; /* bezierPts Is actually a float2, but due to std140 each element needs to be aligned to 16 @@ -57,7 +75,7 @@ BLI_STATIC_ASSERT_ALIGN(struct GPUClipPlanes, 16) struct SimpleLightingData { float4 l_color; - float3 light; + packed_float3 light; float _pad; }; BLI_STATIC_ASSERT_ALIGN(struct SimpleLightingData, 16) diff --git a/source/blender/gpu/GPU_shader_shared_utils.h b/source/blender/gpu/GPU_shader_shared_utils.h index 08fa8be22ef..e1ad3b765f8 100644 --- a/source/blender/gpu/GPU_shader_shared_utils.h +++ b/source/blender/gpu/GPU_shader_shared_utils.h @@ -59,6 +59,7 @@ # define bool2 bvec2 # define bool3 bvec3 # define bool4 bvec4 +# define packed_float3 vec3 # endif #else /* C / C++ */ @@ -83,6 +84,7 @@ using bool1 = int; using bool2 = blender::int2; using bool3 = blender::int3; using bool4 = blender::int4; +using packed_float3 = blender::float3; # else /* C */ typedef float float2[2]; @@ -99,6 +101,7 @@ typedef int bool1; typedef int bool2[2]; typedef int bool3[2]; typedef int bool4[4]; +typedef float3 packed_float3; # endif #endif diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index 979b7cc06cf..5fcb97a2a6b 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -64,13 +64,10 @@ GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageTyp GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC) /** - * (Download and) return a pointer containing the data of a vertex buffer. - * - * Note that the returned pointer is still owned by the driver. To get an - * local copy, use `GPU_vertbuf_unmap` after calling `GPU_vertbuf_read`. + * (Download and) fill data with the data from the vertex buffer. + * NOTE: caller is responsible to reserve enough memory of the data parameter. */ -const void *GPU_vertbuf_read(GPUVertBuf *verts); -void *GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data); +void GPU_vertbuf_read(GPUVertBuf *verts, void *data); /** Same as discard but does not free. */ void GPU_vertbuf_clear(GPUVertBuf *verts); void GPU_vertbuf_discard(GPUVertBuf *); diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index e1876f6d8ac..1acdfb0a1a9 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -40,40 +40,43 @@ GPUBatch *GPU_batch_calloc() return batch; } -GPUBatch *GPU_batch_create_ex(GPUPrimType prim_type, - GPUVertBuf *verts, - GPUIndexBuf *elem, +GPUBatch *GPU_batch_create_ex(GPUPrimType primitive_type, + GPUVertBuf *vertex_buf, + GPUIndexBuf *index_buf, eGPUBatchFlag owns_flag) { GPUBatch *batch = GPU_batch_calloc(); - GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag); + GPU_batch_init_ex(batch, primitive_type, vertex_buf, index_buf, owns_flag); return batch; } void GPU_batch_init_ex(GPUBatch *batch, - GPUPrimType prim_type, - GPUVertBuf *verts, - GPUIndexBuf *elem, + GPUPrimType primitive_type, + GPUVertBuf *vertex_buf, + GPUIndexBuf *index_buf, eGPUBatchFlag owns_flag) { /* Do not pass any other flag */ BLI_assert((owns_flag & ~(GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX)) == 0); + /* Batch needs to be in cleared state. */ + BLI_assert((batch->flag & GPU_BATCH_INIT) == 0); - batch->verts[0] = verts; + batch->verts[0] = vertex_buf; for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; v++) { batch->verts[v] = nullptr; } for (auto &v : batch->inst) { v = nullptr; } - batch->elem = elem; - batch->prim_type = prim_type; + batch->elem = index_buf; + batch->prim_type = primitive_type; batch->flag = owns_flag | GPU_BATCH_INIT | GPU_BATCH_DIRTY; batch->shader = nullptr; } void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src) { + GPU_batch_clear(batch_dst); GPU_batch_init_ex( batch_dst, GPU_PRIM_POINTS, batch_src->verts[0], batch_src->elem, GPU_BATCH_INVALID); @@ -118,35 +121,35 @@ void GPU_batch_discard(GPUBatch *batch) /** \name Buffers Management * \{ */ -void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *inst, bool own_vbo) +void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *vertex_buf, bool own_vbo) { - BLI_assert(inst); + BLI_assert(vertex_buf); batch->flag |= GPU_BATCH_DIRTY; if (batch->inst[0] && (batch->flag & GPU_BATCH_OWNS_INST_VBO)) { GPU_vertbuf_discard(batch->inst[0]); } - batch->inst[0] = inst; + batch->inst[0] = vertex_buf; SET_FLAG_FROM_TEST(batch->flag, own_vbo, GPU_BATCH_OWNS_INST_VBO); } -void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo) +void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *index_buf, bool own_ibo) { - BLI_assert(elem); + BLI_assert(index_buf); batch->flag |= GPU_BATCH_DIRTY; if (batch->elem && (batch->flag & GPU_BATCH_OWNS_INDEX)) { GPU_indexbuf_discard(batch->elem); } - batch->elem = elem; + batch->elem = index_buf; SET_FLAG_FROM_TEST(batch->flag, own_ibo, GPU_BATCH_OWNS_INDEX); } -int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo) +int GPU_batch_instbuf_add(GPUBatch *batch, GPUVertBuf *vertex_buf, bool own_vbo) { - BLI_assert(insts); + BLI_assert(vertex_buf); batch->flag |= GPU_BATCH_DIRTY; for (uint v = 0; v < GPU_BATCH_INST_VBO_MAX_LEN; v++) { @@ -157,7 +160,7 @@ int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo) // BLI_assert(insts->vertex_len == batch->inst[0]->vertex_len); } - batch->inst[v] = insts; + batch->inst[v] = vertex_buf; SET_FLAG_FROM_TEST(batch->flag, own_vbo, (eGPUBatchFlag)(GPU_BATCH_OWNS_INST_VBO << v)); return v; } @@ -167,9 +170,9 @@ int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo) return -1; } -int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo) +int GPU_batch_vertbuf_add(GPUBatch *batch, GPUVertBuf *vertex_buf, bool own_vbo) { - BLI_assert(verts); + BLI_assert(vertex_buf); batch->flag |= GPU_BATCH_DIRTY; for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) { @@ -179,7 +182,7 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo) /* This is an issue for the HACK inside DRW_vbo_request(). */ // BLI_assert(verts->vertex_len == batch->verts[0]->vertex_len); } - batch->verts[v] = verts; + batch->verts[v] = vertex_buf; SET_FLAG_FROM_TEST(batch->flag, own_vbo, (eGPUBatchFlag)(GPU_BATCH_OWNS_VBO << v)); return v; } @@ -189,10 +192,10 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo) return -1; } -bool GPU_batch_vertbuf_has(GPUBatch *batch, GPUVertBuf *verts) +bool GPU_batch_vertbuf_has(GPUBatch *batch, GPUVertBuf *vertex_buf) { for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) { - if (batch->verts[v] == verts) { + if (batch->verts[v] == vertex_buf) { return true; } } @@ -211,7 +214,6 @@ void GPU_batch_resource_id_buf_set(GPUBatch *batch, GPUStorageBuf *resource_id_b /* -------------------------------------------------------------------- */ /** \name Uniform setters * - * TODO(fclem): port this to GPUShader. * \{ */ void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader) @@ -226,19 +228,22 @@ void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader) /** \name Drawing / Drawcall functions * \{ */ -void GPU_batch_draw_parameter_get( - GPUBatch *gpu_batch, int *r_v_count, int *r_v_first, int *r_base_index, int *r_i_count) +void GPU_batch_draw_parameter_get(GPUBatch *gpu_batch, + int *r_vertex_count, + int *r_vertex_first, + int *r_base_index, + int *r_indices_count) { Batch *batch = static_cast(gpu_batch); if (batch->elem) { - *r_v_count = batch->elem_()->index_len_get(); - *r_v_first = batch->elem_()->index_start_get(); + *r_vertex_count = batch->elem_()->index_len_get(); + *r_vertex_first = batch->elem_()->index_start_get(); *r_base_index = batch->elem_()->index_base_get(); } else { - *r_v_count = batch->verts_(0)->vertex_len; - *r_v_first = 0; + *r_vertex_count = batch->verts_(0)->vertex_len; + *r_vertex_first = 0; *r_base_index = -1; } @@ -247,7 +252,7 @@ void GPU_batch_draw_parameter_get( if (batch->inst[1] != nullptr) { i_count = min_ii(i_count, batch->inst_(1)->vertex_len); } - *r_i_count = i_count; + *r_indices_count = i_count; } void GPU_batch_draw(GPUBatch *batch) @@ -256,48 +261,51 @@ void GPU_batch_draw(GPUBatch *batch) GPU_batch_draw_advanced(batch, 0, 0, 0, 0); } -void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count) +void GPU_batch_draw_range(GPUBatch *batch, int vertex_first, int vertex_count) { GPU_shader_bind(batch->shader); - GPU_batch_draw_advanced(batch, v_first, v_count, 0, 0); + GPU_batch_draw_advanced(batch, vertex_first, vertex_count, 0, 0); } -void GPU_batch_draw_instanced(GPUBatch *batch, int i_count) +void GPU_batch_draw_instance_range(GPUBatch *batch, int instance_first, int instance_count) { BLI_assert(batch->inst[0] == nullptr); GPU_shader_bind(batch->shader); - GPU_batch_draw_advanced(batch, 0, 0, 0, i_count); + GPU_batch_draw_advanced(batch, 0, 0, instance_first, instance_count); } -void GPU_batch_draw_advanced( - GPUBatch *gpu_batch, int v_first, int v_count, int i_first, int i_count) +void GPU_batch_draw_advanced(GPUBatch *gpu_batch, + int vertex_first, + int vertex_count, + int instance_first, + int instance_count) { BLI_assert(Context::get()->shader != nullptr); Batch *batch = static_cast(gpu_batch); - if (v_count == 0) { + if (vertex_count == 0) { if (batch->elem) { - v_count = batch->elem_()->index_len_get(); + vertex_count = batch->elem_()->index_len_get(); } else { - v_count = batch->verts_(0)->vertex_len; + vertex_count = batch->verts_(0)->vertex_len; } } - if (i_count == 0) { - i_count = (batch->inst[0]) ? batch->inst_(0)->vertex_len : 1; + if (instance_count == 0) { + instance_count = (batch->inst[0]) ? batch->inst_(0)->vertex_len : 1; /* Meh. This is to be able to use different numbers of verts in instance VBO's. */ if (batch->inst[1] != nullptr) { - i_count = min_ii(i_count, batch->inst_(1)->vertex_len); + instance_count = min_ii(instance_count, batch->inst_(1)->vertex_len); } } - if (v_count == 0 || i_count == 0) { + if (vertex_count == 0 || instance_count == 0) { /* Nothing to draw. */ return; } - batch->draw(v_first, v_count, i_first, i_count); + batch->draw(vertex_first, vertex_count, instance_first, instance_count); } void GPU_batch_draw_indirect(GPUBatch *gpu_batch, GPUStorageBuf *indirect_buf, intptr_t offset) diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 38f80760d61..351334537fe 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -369,7 +369,7 @@ void GPUCodegen::generate_resources() { GPUCodegenCreateInfo &info = *create_info; - /* Ref. T98190: Defines are optimizations for old compilers. + /* Ref. #98190: Defines are optimizations for old compilers. * Might become unnecessary with EEVEE-Next. */ if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_CLEARCOAT)) { info.define("PRINCIPLED_CLEARCOAT"); @@ -889,7 +889,6 @@ void gpu_codegen_init(void) void gpu_codegen_exit(void) { - // BKE_world_defaults_free_gpu(); BKE_material_defaults_free_gpu(); GPU_shader_free_builtin_shaders(); } diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index 81c0a65bb7c..645a920fc83 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -54,7 +54,7 @@ void immBindShader(GPUShader *shader) GPU_shader_bind(shader); GPU_matrix_bind(shader); - GPU_shader_set_srgb_uniform(shader); + Shader::set_srgb_uniform(shader); } void immBindBuiltinProgram(eGPUBuiltinShader shader_id) @@ -163,7 +163,7 @@ static void wide_line_workaround_start(GPUPrimType prim_type) immUniform1f("lineWidth", line_width); if (GPU_blend_get() == GPU_BLEND_NONE) { - /* Disable line smoothing when blending is disabled (see T81827). */ + /* Disable line smoothing when blending is disabled (see #81827). */ immUniform1i("lineSmooth", 0); } @@ -602,19 +602,19 @@ void immUniform1i(const char *name, int x) void immBindTexture(const char *name, GPUTexture *tex) { - int binding = GPU_shader_get_texture_binding(imm->shader, name); + int binding = GPU_shader_get_sampler_binding(imm->shader, name); GPU_texture_bind(tex, binding); } void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state) { - int binding = GPU_shader_get_texture_binding(imm->shader, name); + int binding = GPU_shader_get_sampler_binding(imm->shader, name); GPU_texture_bind_ex(tex, state, binding, true); } void immBindUniformBuf(const char *name, GPUUniformBuf *ubo) { - int binding = GPU_shader_get_uniform_block_binding(imm->shader, name); + int binding = GPU_shader_get_ubo_binding(imm->shader, name); GPU_uniformbuf_bind(ubo, binding); } @@ -625,7 +625,7 @@ void immUniformColor4f(float r, float g, float b, float a) int32_t uniform_loc = GPU_shader_get_builtin_uniform(imm->shader, GPU_UNIFORM_COLOR); BLI_assert(uniform_loc != -1); float data[4] = {r, g, b, a}; - GPU_shader_uniform_vector(imm->shader, uniform_loc, 4, 1, data); + GPU_shader_uniform_float_ex(imm->shader, uniform_loc, 4, 1, data); /* For wide Line workaround. */ copy_v4_v4(imm->uniform_color, data); } diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc index 99e47f5452a..c5fd6ff2206 100644 --- a/source/blender/gpu/intern/gpu_index_buffer.cc +++ b/source/blender/gpu/intern/gpu_index_buffer.cc @@ -399,14 +399,6 @@ void IndexBuf::squeeze_indices_short(uint min_idx, } } -uint32_t *IndexBuf::unmap(const uint32_t *mapped_memory) const -{ - size_t size = size_get(); - uint32_t *result = static_cast(MEM_mallocN(size, __func__)); - memcpy(result, mapped_memory, size); - return result; -} - } // namespace blender::gpu /** \} */ @@ -456,14 +448,9 @@ void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem, unwrap(elem)->init_subrange(unwrap(elem_src), start, length); } -const uint32_t *GPU_indexbuf_read(GPUIndexBuf *elem) +void GPU_indexbuf_read(GPUIndexBuf *elem, uint32_t *data) { - return unwrap(elem)->read(); -} - -uint32_t *GPU_indexbuf_unmap(const GPUIndexBuf *elem, const uint32_t *mapped_buffer) -{ - return unwrap(elem)->unmap(mapped_buffer); + return unwrap(elem)->read(data); } void GPU_indexbuf_discard(GPUIndexBuf *elem) diff --git a/source/blender/gpu/intern/gpu_index_buffer_private.hh b/source/blender/gpu/intern/gpu_index_buffer_private.hh index 4099d6641a6..8689d805f23 100644 --- a/source/blender/gpu/intern/gpu_index_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_index_buffer_private.hh @@ -72,7 +72,7 @@ class IndexBuf { uint32_t index_len_get() const { /* Return 0 to bypass drawing for index buffers full of restart indices. - * They can lead to graphical glitches on some systems. (See T96892) */ + * They can lead to graphical glitches on some systems. (See #96892) */ return is_empty_ ? 0 : index_len_; } uint32_t index_start_get() const @@ -98,8 +98,7 @@ class IndexBuf { virtual void bind_as_ssbo(uint binding) = 0; - virtual const uint32_t *read() const = 0; - uint32_t *unmap(const uint32_t *mapped_memory) const; + virtual void read(uint32_t *data) const = 0; virtual void update_sub(uint start, uint len, const void *data) = 0; diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index af9e0acd3ec..d0881ea4814 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -647,21 +647,6 @@ char *GPU_material_split_sub_function(GPUMaterial *material, SNPRINTF(func_link->name, "ntree_fn%d", material->generated_function_len++); BLI_addtail(&material->graph.material_functions, func_link); - /* Set value to break the link with the main graph. */ - switch (return_type) { - case GPU_FLOAT: - GPU_link(material, "set_value_one", link); - break; - case GPU_VEC3: - GPU_link(material, "set_rgb_one", link); - break; - case GPU_VEC4: - GPU_link(material, "set_rgba_one", link); - break; - default: - BLI_assert(0); - break; - } return func_link->name; } @@ -850,7 +835,6 @@ void GPU_materials_free(Main *bmain) GPU_material_free(&wo->gpumaterial); } - // BKE_world_defaults_free_gpu(); BKE_material_defaults_free_gpu(); } diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc index b46860cf0f4..d285ff5ef99 100644 --- a/source/blender/gpu/intern/gpu_matrix.cc +++ b/source/blender/gpu/intern/gpu_matrix.cc @@ -623,30 +623,31 @@ void GPU_matrix_bind(GPUShader *shader) int32_t P_inv = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_PROJECTION_INV); if (MV != -1) { - GPU_shader_uniform_vector( + GPU_shader_uniform_float_ex( shader, MV, 16, 1, (const float *)GPU_matrix_model_view_get(nullptr)); } if (P != -1) { - GPU_shader_uniform_vector(shader, P, 16, 1, (const float *)GPU_matrix_projection_get(nullptr)); + GPU_shader_uniform_float_ex( + shader, P, 16, 1, (const float *)GPU_matrix_projection_get(nullptr)); } if (MVP != -1) { - GPU_shader_uniform_vector( + GPU_shader_uniform_float_ex( shader, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(nullptr)); } if (N != -1) { - GPU_shader_uniform_vector(shader, N, 9, 1, (const float *)GPU_matrix_normal_get(nullptr)); + GPU_shader_uniform_float_ex(shader, N, 9, 1, (const float *)GPU_matrix_normal_get(nullptr)); } if (MV_inv != -1) { Mat4 m; GPU_matrix_model_view_get(m); invert_m4(m); - GPU_shader_uniform_vector(shader, MV_inv, 16, 1, (const float *)m); + GPU_shader_uniform_float_ex(shader, MV_inv, 16, 1, (const float *)m); } if (P_inv != -1) { Mat4 m; GPU_matrix_projection_get(m); invert_m4(m); - GPU_shader_uniform_vector(shader, P_inv, 16, 1, (const float *)m); + GPU_shader_uniform_float_ex(shader, P_inv, 16, 1, (const float *)m); } gpu_matrix_state_active_set_dirty(false); diff --git a/source/blender/gpu/intern/gpu_node_graph.cc b/source/blender/gpu/intern/gpu_node_graph.cc index 8f51a6b91aa..2c905f8474b 100644 --- a/source/blender/gpu/intern/gpu_node_graph.cc +++ b/source/blender/gpu/intern/gpu_node_graph.cc @@ -149,7 +149,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType case GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN: input->source = GPU_SOURCE_FUNCTION_CALL; /* NOTE(@fclem): End of function call is the return variable set during codegen. */ - SNPRINTF(input->function_call, "dF_branch(%s(), ", link->function_name); + SNPRINTF(input->function_call, "dF_branch_incomplete(%s(), ", link->function_name); break; default: break; diff --git a/source/blender/gpu/intern/gpu_select_sample_query.cc b/source/blender/gpu/intern/gpu_select_sample_query.cc index 7393dfd0d81..0912e0a3b20 100644 --- a/source/blender/gpu/intern/gpu_select_sample_query.cc +++ b/source/blender/gpu/intern/gpu_select_sample_query.cc @@ -79,7 +79,7 @@ void gpu_select_query_begin(GPUSelectResult *buffer, GPU_scissor_get(g_query_state.scissor); GPU_viewport_size_get_i(g_query_state.viewport); - /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see T7997). */ + /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see #7997). */ GPU_color_mask(true, true, true, true); /* In order to save some fill rate we minimize the viewport using rect. @@ -98,7 +98,7 @@ void gpu_select_query_begin(GPUSelectResult *buffer, * objects in the view frustum independently of their order, we need to disable the depth test */ if (mode == GPU_SELECT_ALL) { /* #glQueries on Windows+Intel drivers only works with depth testing turned on. - * See T62947 for details */ + * See #62947 for details */ GPU_depth_test(GPU_DEPTH_ALWAYS); GPU_depth_mask(true); } diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 0653ae11a0a..0edc2072302 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -46,8 +46,6 @@ std::string Shader::defines_declare(const shader::ShaderCreateInfo &info) const using namespace blender; using namespace blender::gpu; -static bool gpu_shader_srgb_uniform_dirty_get(); - /* -------------------------------------------------------------------- */ /** \name Creation / Destruction * \{ */ @@ -443,58 +441,6 @@ GPUShader *GPU_shader_create_from_python(const char *vertcode, return sh; } -static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc) -{ - bool is_alloc = false; - if (str_arr == nullptr) { - *r_is_alloc = false; - return nullptr; - } - /* Skip empty strings (avoid alloc if we can). */ - while (str_arr[0] && str_arr[0][0] == '\0') { - str_arr++; - } - int i; - for (i = 0; str_arr[i]; i++) { - if (i != 0 && str_arr[i][0] != '\0') { - is_alloc = true; - } - } - *r_is_alloc = is_alloc; - if (is_alloc) { - return BLI_string_join_arrayN(str_arr, i); - } - - return str_arr[0]; -} - -struct GPUShader *GPU_shader_create_from_arrays_impl( - const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line) -{ - struct { - const char *str; - bool is_alloc; - } str_dst[4] = {{nullptr}}; - const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs}; - - for (int i = 0; i < ARRAY_SIZE(str_src); i++) { - str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc); - } - - char name[64]; - BLI_snprintf(name, sizeof(name), "%s_%d", func, line); - - GPUShader *sh = GPU_shader_create( - str_dst[0].str, str_dst[1].str, str_dst[2].str, nullptr, str_dst[3].str, name); - - for (auto &i : str_dst) { - if (i.is_alloc) { - MEM_freeN((void *)i.str); - } - } - return sh; -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -511,11 +457,11 @@ void GPU_shader_bind(GPUShader *gpu_shader) ctx->shader = shader; shader->bind(); GPU_matrix_bind(gpu_shader); - GPU_shader_set_srgb_uniform(gpu_shader); + Shader::set_srgb_uniform(gpu_shader); } else { - if (gpu_shader_srgb_uniform_dirty_get()) { - GPU_shader_set_srgb_uniform(gpu_shader); + if (Shader::srgb_uniform_dirty_get()) { + Shader::set_srgb_uniform(gpu_shader); } if (GPU_matrix_dirty_get()) { GPU_matrix_bind(gpu_shader); @@ -580,66 +526,60 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader) int GPU_shader_get_uniform(GPUShader *shader, const char *name) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *uniform = interface->uniform_get(name); return uniform ? uniform->location : -1; } int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; return interface->uniform_builtin((GPUUniformBuiltin)builtin); } int GPU_shader_get_builtin_block(GPUShader *shader, int builtin) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; return interface->ubo_builtin((GPUUniformBlockBuiltin)builtin); } -int GPU_shader_get_builtin_ssbo(GPUShader *shader, int builtin) +int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name) { - ShaderInterface *interface = unwrap(shader)->interface; - return interface->ssbo_builtin((GPUStorageBufferBuiltin)builtin); -} - -int GPU_shader_get_ssbo(GPUShader *shader, const char *name) -{ - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *ssbo = interface->ssbo_get(name); return ssbo ? ssbo->location : -1; } int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *ubo = interface->ubo_get(name); return ubo ? ubo->location : -1; } -int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name) +int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *ubo = interface->ubo_get(name); return ubo ? ubo->binding : -1; } -int GPU_shader_get_texture_binding(GPUShader *shader, const char *name) +int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *tex = interface->uniform_get(name); return tex ? tex->binding : -1; } uint GPU_shader_get_attribute_len(const GPUShader *shader) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; return interface->attr_len_; } -int GPU_shader_get_attribute(GPUShader *shader, const char *name) +int GPU_shader_get_attribute(const GPUShader *shader, const char *name) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *attr = interface->attr_get(name); return attr ? attr->location : -1; } @@ -649,7 +589,7 @@ bool GPU_shader_get_attribute_info(const GPUShader *shader, char r_name[256], int *r_type) { - ShaderInterface *interface = unwrap(shader)->interface; + const ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *attr = interface->attr_get(attr_location); if (!attr) { @@ -678,32 +618,22 @@ int GPU_shader_get_program(GPUShader *shader) /** \name Uniforms setters * \{ */ -void GPU_shader_uniform_vector( - GPUShader *shader, int loc, int len, int arraysize, const float *value) +void GPU_shader_uniform_float_ex( + GPUShader *shader, int loc, int len, int array_size, const float *value) { - unwrap(shader)->uniform_float(loc, len, arraysize, value); + unwrap(shader)->uniform_float(loc, len, array_size, value); } -void GPU_shader_uniform_vector_int( - GPUShader *shader, int loc, int len, int arraysize, const int *value) +void GPU_shader_uniform_int_ex( + GPUShader *shader, int loc, int len, int array_size, const int *value) { - unwrap(shader)->uniform_int(loc, len, arraysize, value); -} - -void GPU_shader_uniform_int(GPUShader *shader, int location, int value) -{ - GPU_shader_uniform_vector_int(shader, location, 1, 1, &value); -} - -void GPU_shader_uniform_float(GPUShader *shader, int location, float value) -{ - GPU_shader_uniform_vector(shader, location, 1, 1, &value); + unwrap(shader)->uniform_int(loc, len, array_size, value); } void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_int(sh, loc, value); + GPU_shader_uniform_int_ex(sh, loc, 1, 1, &value); } void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value) @@ -732,37 +662,37 @@ void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, fl void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_float(sh, loc, value); + GPU_shader_uniform_float_ex(sh, loc, 1, 1, &value); } void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector(sh, loc, 2, 1, data); + GPU_shader_uniform_float_ex(sh, loc, 2, 1, data); } void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector(sh, loc, 3, 1, data); + GPU_shader_uniform_float_ex(sh, loc, 3, 1, data); } void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector(sh, loc, 4, 1, data); + GPU_shader_uniform_float_ex(sh, loc, 4, 1, data); } void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector_int(sh, loc, 2, 1, data); + GPU_shader_uniform_int_ex(sh, loc, 2, 1, data); } void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector(sh, loc, 16, 1, (const float *)data); + GPU_shader_uniform_float_ex(sh, loc, 16, 1, (const float *)data); } void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3]) @@ -775,13 +705,13 @@ void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const floa void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector(sh, loc, 2, len, (const float *)val); + GPU_shader_uniform_float_ex(sh, loc, 2, len, (const float *)val); } void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]) { const int loc = GPU_shader_get_uniform(sh, name); - GPU_shader_uniform_vector(sh, loc, 4, len, (const float *)val); + GPU_shader_uniform_float_ex(sh, loc, 4, len, (const float *)val); } /** \} */ @@ -797,24 +727,26 @@ void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, cons * frame-buffer color-space. * \{ */ +namespace blender::gpu { + static int g_shader_builtin_srgb_transform = 0; static bool g_shader_builtin_srgb_is_dirty = false; -static bool gpu_shader_srgb_uniform_dirty_get() +bool Shader::srgb_uniform_dirty_get() { return g_shader_builtin_srgb_is_dirty; } -void GPU_shader_set_srgb_uniform(GPUShader *shader) +void Shader::set_srgb_uniform(GPUShader *shader) { int32_t loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_SRGB_TRANSFORM); if (loc != -1) { - GPU_shader_uniform_vector_int(shader, loc, 1, 1, &g_shader_builtin_srgb_transform); + GPU_shader_uniform_int_ex(shader, loc, 1, 1, &g_shader_builtin_srgb_transform); } g_shader_builtin_srgb_is_dirty = false; } -void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear) +void Shader::set_framebuffer_srgb_target(int use_srgb_to_linear) { if (g_shader_builtin_srgb_transform != use_srgb_to_linear) { g_shader_builtin_srgb_transform = use_srgb_to_linear; @@ -822,4 +754,6 @@ void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear) } } +} // namespace blender::gpu + /** \} */ diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c deleted file mode 100644 index 470643ba863..00000000000 --- a/source/blender/gpu/intern/gpu_shader_builtin.c +++ /dev/null @@ -1,404 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2005 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup gpu - */ - -#include "BLI_utildefines.h" - -#include "GPU_shader.h" - -/* Adjust these constants as needed. */ -#define MAX_DEFINE_LENGTH 256 -#define MAX_EXT_DEFINE_LENGTH 512 - -/* Non-generated shaders */ -extern char datatoc_gpu_shader_depth_only_frag_glsl[]; -extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; -extern char datatoc_gpu_shader_checker_frag_glsl[]; -extern char datatoc_gpu_shader_diag_stripes_frag_glsl[]; -extern char datatoc_gpu_shader_simple_lighting_frag_glsl[]; -extern char datatoc_gpu_shader_flat_color_frag_glsl[]; -extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[]; -extern char datatoc_gpu_shader_flat_id_frag_glsl[]; -extern char datatoc_gpu_shader_2D_area_borders_vert_glsl[]; -extern char datatoc_gpu_shader_2D_area_borders_frag_glsl[]; -extern char datatoc_gpu_shader_2D_vert_glsl[]; -extern char datatoc_gpu_shader_2D_smooth_color_uniform_alpha_vert_glsl[]; -extern char datatoc_gpu_shader_2D_image_vert_glsl[]; -extern char datatoc_gpu_shader_2D_image_rect_vert_glsl[]; -extern char datatoc_gpu_shader_2D_image_multi_rect_vert_glsl[]; -extern char datatoc_gpu_shader_2D_widget_base_vert_glsl[]; -extern char datatoc_gpu_shader_2D_widget_base_frag_glsl[]; -extern char datatoc_gpu_shader_2D_widget_shadow_vert_glsl[]; -extern char datatoc_gpu_shader_2D_widget_shadow_frag_glsl[]; -extern char datatoc_gpu_shader_2D_nodelink_frag_glsl[]; -extern char datatoc_gpu_shader_2D_nodelink_vert_glsl[]; - -extern char datatoc_gpu_shader_3D_image_vert_glsl[]; -extern char datatoc_gpu_shader_image_frag_glsl[]; -extern char datatoc_gpu_shader_image_overlays_merge_frag_glsl[]; -extern char datatoc_gpu_shader_image_overlays_stereo_merge_frag_glsl[]; -extern char datatoc_gpu_shader_image_color_frag_glsl[]; -extern char datatoc_gpu_shader_image_desaturate_frag_glsl[]; -extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[]; -extern char datatoc_gpu_shader_image_varying_color_frag_glsl[]; -extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[]; -extern char datatoc_gpu_shader_3D_vert_glsl[]; -extern char datatoc_gpu_shader_3D_normal_vert_glsl[]; -extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[]; -extern char datatoc_gpu_shader_3D_polyline_frag_glsl[]; -extern char datatoc_gpu_shader_3D_polyline_geom_glsl[]; -extern char datatoc_gpu_shader_3D_polyline_vert_glsl[]; -extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[]; -extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; -extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[]; -extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[]; - -extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[]; - -extern char datatoc_gpu_shader_point_uniform_color_aa_frag_glsl[]; -extern char datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl[]; -extern char datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl[]; -extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; -extern char datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl[]; -extern char datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl[]; -extern char datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl[]; -extern char datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl[]; -extern char datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl[]; - -extern char datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl[]; -extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[]; -extern char datatoc_gpu_shader_3D_line_dashed_uniform_color_vert_glsl[]; - -extern char datatoc_gpu_shader_text_vert_glsl[]; -extern char datatoc_gpu_shader_text_frag_glsl[]; -extern char datatoc_gpu_shader_keyframe_shape_vert_glsl[]; -extern char datatoc_gpu_shader_keyframe_shape_frag_glsl[]; - -extern char datatoc_gpu_shader_gpencil_stroke_vert_glsl[]; -extern char datatoc_gpu_shader_gpencil_stroke_frag_glsl[]; -extern char datatoc_gpu_shader_gpencil_stroke_geom_glsl[]; - -extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[]; - -extern char datatoc_gpu_shader_colorspace_lib_glsl[]; - -const struct GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN] = { - [GPU_SHADER_CFG_DEFAULT] = - { - .lib = "", - .def = "#define blender_srgb_to_framebuffer_space(a) a\n", - }, - [GPU_SHADER_CFG_CLIPPED] = - { - .lib = datatoc_gpu_shader_cfg_world_clip_lib_glsl, - .def = "#define USE_WORLD_CLIP_PLANES\n" - "#define blender_srgb_to_framebuffer_space(a) a\n", - }, -}; - -/* cache of built-in shaders (each is created on first use) */ -static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {{NULL}}; - -typedef struct { - const char *name; - const char *vert; - /** Optional. */ - const char *geom; - const char *frag; - /** Optional. */ - const char *defs; - - const char *create_info; - const char *clipped_create_info; -} GPUShaderStages; - -static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { - [GPU_SHADER_TEXT] = - { - .name = "GPU_SHADER_TEXT", - .create_info = "gpu_shader_text", - }, - [GPU_SHADER_KEYFRAME_SHAPE] = - { - .name = "GPU_SHADER_KEYFRAME_SHAPE", - .create_info = "gpu_shader_keyframe_shape", - }, - [GPU_SHADER_SIMPLE_LIGHTING] = - { - .name = "GPU_SHADER_SIMPLE_LIGHTING", - .create_info = "gpu_shader_simple_lighting", - }, - [GPU_SHADER_3D_IMAGE] = - { - .name = "GPU_SHADER_3D_IMAGE", - .create_info = "gpu_shader_3D_image", - }, - [GPU_SHADER_3D_IMAGE_COLOR] = - { - .name = "GPU_SHADER_3D_IMAGE_COLOR", - .create_info = "gpu_shader_3D_image_color", - }, - [GPU_SHADER_2D_CHECKER] = - { - .name = "GPU_SHADER_2D_CHECKER", - .create_info = "gpu_shader_2D_checker", - }, - - [GPU_SHADER_2D_DIAG_STRIPES] = - { - .name = "GPU_SHADER_2D_DIAG_STRIPES", - .create_info = "gpu_shader_2D_diag_stripes", - }, - - [GPU_SHADER_ICON] = - { - .name = "GPU_SHADER_ICON", - .create_info = "gpu_shader_icon", - }, - [GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] = - { - .name = "GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE", - .create_info = "gpu_shader_2D_image_overlays_merge", - }, - [GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE] = - { - .name = "GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE", - .create_info = "gpu_shader_2D_image_overlays_stereo_merge", - }, - [GPU_SHADER_2D_IMAGE_DESATURATE_COLOR] = - { - .name = "GPU_SHADER_2D_IMAGE_DESATURATE_COLOR", - .create_info = "gpu_shader_2D_image_desaturate_color", - }, - [GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = - { - .name = "GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR", - .create_info = "gpu_shader_2D_image_shuffle_color", - }, - [GPU_SHADER_2D_IMAGE_RECT_COLOR] = - { - .name = "GPU_SHADER_2D_IMAGE_RECT_COLOR", - .create_info = "gpu_shader_2D_image_rect_color", - }, - [GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR] = - { - .name = "GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR", - .create_info = "gpu_shader_2D_image_multi_rect_color", - }, - - [GPU_SHADER_3D_UNIFORM_COLOR] = - { - .name = "GPU_SHADER_3D_UNIFORM_COLOR", - .create_info = "gpu_shader_3D_uniform_color", - .clipped_create_info = "gpu_shader_3D_uniform_color_clipped", - }, - [GPU_SHADER_3D_FLAT_COLOR] = - { - .name = "GPU_SHADER_3D_FLAT_COLOR", - .create_info = "gpu_shader_3D_flat_color", - .clipped_create_info = "gpu_shader_3D_flat_color_clipped", - }, - [GPU_SHADER_3D_SMOOTH_COLOR] = - { - .name = "GPU_SHADER_3D_SMOOTH_COLOR", - .create_info = "gpu_shader_3D_smooth_color", - .clipped_create_info = "gpu_shader_3D_smooth_color_clipped", - }, - [GPU_SHADER_3D_DEPTH_ONLY] = - { - .name = "GPU_SHADER_3D_DEPTH_ONLY", - .create_info = "gpu_shader_3D_depth_only", - .clipped_create_info = "gpu_shader_3D_depth_only_clipped", - }, - [GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] = - { - .name = "GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR", - .create_info = "gpu_shader_3D_clipped_uniform_color", - }, - - [GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR] = - { - .name = "GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR", - .create_info = "gpu_shader_3D_polyline_uniform_color", - }, - [GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR] = - { - .name = "GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR", - .create_info = "gpu_shader_3D_polyline_uniform_color_clipped", - }, - [GPU_SHADER_3D_POLYLINE_FLAT_COLOR] = - { - .name = "GPU_SHADER_3D_POLYLINE_FLAT_COLOR", - .create_info = "gpu_shader_3D_polyline_flat_color", - }, - [GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR] = - { - .name = "GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR", - .create_info = "gpu_shader_3D_polyline_smooth_color", - }, - - [GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR] = - { - .name = "GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR", - .create_info = "gpu_shader_3D_line_dashed_uniform_color", - .clipped_create_info = "gpu_shader_3D_line_dashed_uniform_color_clipped", - }, - - [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] = - { - .name = "GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA", - .create_info = "gpu_shader_2D_point_uniform_size_uniform_color_aa", - }, - [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] = - { - .name = "GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA", - .create_info = "gpu_shader_2D_point_uniform_size_uniform_color_outline_aa", - }, - [GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR] = - { - .name = "GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR", - .create_info = "gpu_shader_3D_point_fixed_size_varying_color", - }, - [GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR] = - { - .name = "GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR", - .create_info = "gpu_shader_3D_point_varying_size_varying_color", - }, - [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] = - { - .name = "GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA", - .create_info = "gpu_shader_3D_point_uniform_size_uniform_color_aa", - .clipped_create_info = "gpu_shader_3D_point_uniform_size_uniform_color_aa_clipped", - }, - - [GPU_SHADER_2D_AREA_BORDERS] = - { - .name = "GPU_SHADER_2D_AREA_BORDERS", - .create_info = "gpu_shader_2D_area_borders", - }, - [GPU_SHADER_2D_WIDGET_BASE] = - { - .name = "GPU_SHADER_2D_WIDGET_BASE", - .create_info = "gpu_shader_2D_widget_base", - }, - [GPU_SHADER_2D_WIDGET_BASE_INST] = - { - .name = "GPU_SHADER_2D_WIDGET_BASE_INST", - .defs = "#define USE_INSTANCE\n", - .create_info = "gpu_shader_2D_widget_base_inst", - }, - [GPU_SHADER_2D_WIDGET_SHADOW] = - { - .name = "GPU_SHADER_2D_WIDGET_SHADOW", - .create_info = "gpu_shader_2D_widget_shadow", - }, - [GPU_SHADER_2D_NODELINK] = - { - .name = "GPU_SHADER_2D_NODELINK", - .create_info = "gpu_shader_2D_nodelink", - }, - - [GPU_SHADER_2D_NODELINK_INST] = - { - .name = "GPU_SHADER_2D_NODELINK_INST", - .create_info = "gpu_shader_2D_nodelink_inst", - }, - - [GPU_SHADER_GPENCIL_STROKE] = - { - .name = "GPU_SHADER_GPENCIL_STROKE", - .create_info = "gpu_shader_gpencil_stroke", - }, -}; - -GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, - eGPUShaderConfig sh_cfg) -{ - BLI_assert(shader < GPU_SHADER_BUILTIN_LEN); - BLI_assert(sh_cfg < GPU_SHADER_CFG_LEN); - GPUShader **sh_p = &builtin_shaders[sh_cfg][shader]; - - if (*sh_p == NULL) { - const GPUShaderStages *stages = &builtin_shader_stages[shader]; - - /* common case */ - if (sh_cfg == GPU_SHADER_CFG_DEFAULT) { - if (stages->create_info != NULL) { - *sh_p = GPU_shader_create_from_info_name(stages->create_info); - if (ELEM(shader, - GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR, - GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, - GPU_SHADER_3D_POLYLINE_FLAT_COLOR, - GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR)) { - /* Set a default value for `lineSmooth`. - * Ideally this value should be set by the caller. */ - GPU_shader_bind(*sh_p); - GPU_shader_uniform_1i(*sh_p, "lineSmooth", 1); - } - } - else { - *sh_p = GPU_shader_create_from_arrays_named( - stages->name, - { - .vert = (const char *[]){stages->vert, NULL}, - .geom = (const char *[]){stages->geom, NULL}, - .frag = - (const char *[]){datatoc_gpu_shader_colorspace_lib_glsl, stages->frag, NULL}, - .defs = (const char *[]){stages->defs, NULL}, - }); - } - } - else if (sh_cfg == GPU_SHADER_CFG_CLIPPED) { - /* Remove eventually, for now ensure support for each shader has been added. */ - BLI_assert(ELEM(shader, - GPU_SHADER_3D_UNIFORM_COLOR, - GPU_SHADER_3D_SMOOTH_COLOR, - GPU_SHADER_3D_DEPTH_ONLY, - GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, - GPU_SHADER_3D_FLAT_COLOR, - GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR)); - /* In rare cases geometry shaders calculate clipping themselves. */ - if (stages->clipped_create_info != NULL) { - *sh_p = GPU_shader_create_from_info_name(stages->clipped_create_info); - } - else { - const char *world_clip_lib = datatoc_gpu_shader_cfg_world_clip_lib_glsl; - const char *world_clip_def = "#define USE_WORLD_CLIP_PLANES\n"; - *sh_p = GPU_shader_create_from_arrays_named( - stages->name, - { - .vert = (const char *[]){world_clip_lib, stages->vert, NULL}, - .geom = (const char *[]){stages->geom ? world_clip_lib : NULL, stages->geom, NULL}, - .frag = - (const char *[]){datatoc_gpu_shader_colorspace_lib_glsl, stages->frag, NULL}, - .defs = (const char *[]){world_clip_def, stages->defs, NULL}, - }); - } - } - else { - BLI_assert(0); - } - } - - return *sh_p; -} - -GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader) -{ - return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT); -} - -void GPU_shader_free_builtin_shaders(void) -{ - for (int i = 0; i < GPU_SHADER_CFG_LEN; i++) { - for (int j = 0; j < GPU_SHADER_BUILTIN_LEN; j++) { - if (builtin_shaders[i][j]) { - GPU_shader_free(builtin_shaders[i][j]); - builtin_shaders[i][j] = NULL; - } - } - } -} diff --git a/source/blender/gpu/intern/gpu_shader_builtin.cc b/source/blender/gpu/intern/gpu_shader_builtin.cc new file mode 100644 index 00000000000..2a15e6d823d --- /dev/null +++ b/source/blender/gpu/intern/gpu_shader_builtin.cc @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2005 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#include "BLI_utildefines.h" + +#include "GPU_shader.h" + +/* Cache of built-in shaders (each is created on first use). */ +static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {{nullptr}}; + +static const char *builtin_shader_create_info_name(eGPUBuiltinShader shader) +{ + switch (shader) { + case GPU_SHADER_TEXT: + return "gpu_shader_text"; + case GPU_SHADER_KEYFRAME_SHAPE: + return "gpu_shader_keyframe_shape"; + case GPU_SHADER_SIMPLE_LIGHTING: + return "gpu_shader_simple_lighting"; + case GPU_SHADER_3D_IMAGE: + return "gpu_shader_3D_image"; + case GPU_SHADER_3D_IMAGE_COLOR: + return "gpu_shader_3D_image_color"; + case GPU_SHADER_2D_CHECKER: + return "gpu_shader_2D_checker"; + case GPU_SHADER_2D_DIAG_STRIPES: + return "gpu_shader_2D_diag_stripes"; + case GPU_SHADER_ICON: + return "gpu_shader_icon"; + case GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE: + return "gpu_shader_2D_image_overlays_merge"; + case GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE: + return "gpu_shader_2D_image_overlays_stereo_merge"; + case GPU_SHADER_2D_IMAGE_DESATURATE_COLOR: + return "gpu_shader_2D_image_desaturate_color"; + case GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR: + return "gpu_shader_2D_image_shuffle_color"; + case GPU_SHADER_2D_IMAGE_RECT_COLOR: + return "gpu_shader_2D_image_rect_color"; + case GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR: + return "gpu_shader_2D_image_multi_rect_color"; + case GPU_SHADER_3D_UNIFORM_COLOR: + return "gpu_shader_3D_uniform_color"; + case GPU_SHADER_3D_FLAT_COLOR: + return "gpu_shader_3D_flat_color"; + case GPU_SHADER_3D_SMOOTH_COLOR: + return "gpu_shader_3D_smooth_color"; + case GPU_SHADER_3D_DEPTH_ONLY: + return "gpu_shader_3D_depth_only"; + case GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR: + return "gpu_shader_3D_clipped_uniform_color"; + case GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR: + return "gpu_shader_3D_polyline_uniform_color"; + case GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR: + return "gpu_shader_3D_polyline_uniform_color_clipped"; + case GPU_SHADER_3D_POLYLINE_FLAT_COLOR: + return "gpu_shader_3D_polyline_flat_color"; + case GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR: + return "gpu_shader_3D_polyline_smooth_color"; + case GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR: + return "gpu_shader_3D_line_dashed_uniform_color"; + case GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA: + return "gpu_shader_2D_point_uniform_size_uniform_color_aa"; + case GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA: + return "gpu_shader_2D_point_uniform_size_uniform_color_outline_aa"; + case GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR: + return "gpu_shader_3D_point_varying_size_varying_color"; + case GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA: + return "gpu_shader_3D_point_uniform_size_uniform_color_aa"; + case GPU_SHADER_2D_AREA_BORDERS: + return "gpu_shader_2D_area_borders"; + case GPU_SHADER_2D_WIDGET_BASE: + return "gpu_shader_2D_widget_base"; + case GPU_SHADER_2D_WIDGET_BASE_INST: + return "gpu_shader_2D_widget_base_inst"; + case GPU_SHADER_2D_WIDGET_SHADOW: + return "gpu_shader_2D_widget_shadow"; + case GPU_SHADER_2D_NODELINK: + return "gpu_shader_2D_nodelink"; + case GPU_SHADER_2D_NODELINK_INST: + return "gpu_shader_2D_nodelink_inst"; + case GPU_SHADER_GPENCIL_STROKE: + return "gpu_shader_gpencil_stroke"; + default: + BLI_assert_unreachable(); + return ""; + } +} + +static const char *builtin_shader_create_info_name_clipped(eGPUBuiltinShader shader) +{ + switch (shader) { + case GPU_SHADER_3D_UNIFORM_COLOR: + return "gpu_shader_3D_uniform_color_clipped"; + case GPU_SHADER_3D_FLAT_COLOR: + return "gpu_shader_3D_flat_color_clipped"; + case GPU_SHADER_3D_SMOOTH_COLOR: + return "gpu_shader_3D_smooth_color_clipped"; + case GPU_SHADER_3D_DEPTH_ONLY: + return "gpu_shader_3D_depth_only_clipped"; + case GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR: + return "gpu_shader_3D_line_dashed_uniform_color_clipped"; + case GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA: + return "gpu_shader_3D_point_uniform_size_uniform_color_aa_clipped"; + default: + BLI_assert_unreachable(); + return ""; + } +} + +GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, + eGPUShaderConfig sh_cfg) +{ + BLI_assert(shader < GPU_SHADER_BUILTIN_LEN); + BLI_assert(sh_cfg < GPU_SHADER_CFG_LEN); + GPUShader **sh_p = &builtin_shaders[sh_cfg][shader]; + + if (*sh_p == nullptr) { + if (sh_cfg == GPU_SHADER_CFG_DEFAULT) { + /* Common case. */ + *sh_p = GPU_shader_create_from_info_name(builtin_shader_create_info_name(shader)); + if (ELEM(shader, + GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR, + GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR, + GPU_SHADER_3D_POLYLINE_FLAT_COLOR, + GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR)) { + /* Set a default value for `lineSmooth`. + * Ideally this value should be set by the caller. */ + GPU_shader_bind(*sh_p); + GPU_shader_uniform_1i(*sh_p, "lineSmooth", 1); + } + } + else if (sh_cfg == GPU_SHADER_CFG_CLIPPED) { + /* In rare cases geometry shaders calculate clipping themselves. */ + *sh_p = GPU_shader_create_from_info_name(builtin_shader_create_info_name_clipped(shader)); + } + else { + BLI_assert(0); + } + } + + return *sh_p; +} + +GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader) +{ + return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT); +} + +void GPU_shader_free_builtin_shaders(void) +{ + for (int i = 0; i < GPU_SHADER_CFG_LEN; i++) { + for (int j = 0; j < GPU_SHADER_BUILTIN_LEN; j++) { + if (builtin_shaders[i][j]) { + GPU_shader_free(builtin_shaders[i][j]); + builtin_shaders[i][j] = nullptr; + } + } + } +} diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc index 605ff585ff8..8b3643e9cc8 100644 --- a/source/blender/gpu/intern/gpu_shader_dependency.cc +++ b/source/blender/gpu/intern/gpu_shader_dependency.cc @@ -194,7 +194,7 @@ struct GPUSource { /** * Some drivers completely forbid quote characters even in unused preprocessor directives. * We fix the cases where we can't manually patch in `enum_preprocess()`. - * This check ensure none are present in non-patched sources. (see T97545) + * This check ensure none are present in non-patched sources. (see #97545) */ void check_no_quotes() { @@ -214,7 +214,7 @@ struct GPUSource { /** * Some drivers completely forbid string characters even in unused preprocessor directives. - * This fixes the cases we cannot manually patch: Shared headers #includes. (see T97545) + * This fixes the cases we cannot manually patch: Shared headers #includes. (see #97545) * TODO(fclem): This could be done during the datatoc step. */ void quote_preprocess() diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh index c27b5cc1a37..fc9eafca3a5 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.hh +++ b/source/blender/gpu/intern/gpu_shader_interface.hh @@ -57,7 +57,6 @@ class ShaderInterface { /** Location of builtin uniforms. Fast access, no lookup needed. */ int32_t builtins_[GPU_NUM_UNIFORMS]; int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]; - int32_t builtin_buffers_[GPU_NUM_STORAGE_BUFFERS]; /** * Currently only used for `GPU_shader_get_attribute_info`. @@ -128,17 +127,9 @@ class ShaderInterface { return builtin_blocks_[builtin]; } - /* Returns binding position. */ - inline int32_t ssbo_builtin(const GPUStorageBufferBuiltin builtin) const - { - BLI_assert(builtin >= 0 && builtin < GPU_NUM_STORAGE_BUFFERS); - return builtin_buffers_[builtin]; - } - protected: static inline const char *builtin_uniform_name(GPUUniformBuiltin u); static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u); - static inline const char *builtin_storage_block_name(GPUStorageBufferBuiltin u); inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const; inline void copy_input_name(ShaderInput *input, @@ -234,18 +225,6 @@ inline const char *ShaderInterface::builtin_uniform_block_name(GPUUniformBlockBu } } -inline const char *ShaderInterface::builtin_storage_block_name(GPUStorageBufferBuiltin u) -{ - switch (u) { - case GPU_STORAGE_BUFFER_DEBUG_VERTS: - return "drw_debug_verts_buf"; - case GPU_STORAGE_BUFFER_DEBUG_PRINT: - return "drw_debug_print_buf"; - default: - return nullptr; - } -} - /* Returns string length including '\0' terminator. */ inline uint32_t ShaderInterface::set_input_name(ShaderInput *input, char *name, diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index a822cd8aa38..e4d036a9554 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -71,6 +71,10 @@ class Shader { return name; }; + static bool srgb_uniform_dirty_get(); + static void set_srgb_uniform(GPUShader *shader); + static void set_framebuffer_srgb_target(int use_srgb_to_linear); + protected: void print_log( Span sources, char *log, const char *stage, bool error, GPULogParser *parser); diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index 09a5b0ac6e9..6027aaec6b3 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -322,7 +322,7 @@ void GPU_bgl_start() } StateManager &state_manager = *(Context::get()->state_manager); if (state_manager.use_bgl == false) { - /* Expected by many addons (see T80169, T81289). + /* Expected by many addons (see #80169, #81289). * This will reset the blend function. */ GPU_blend(GPU_BLEND_NONE); diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 562bdd32860..f3986749d28 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -602,7 +602,7 @@ void *GPU_texture_read(GPUTexture *tex_, eGPUDataFormat data_format, int miplvl) BLI_assert_msg( GPU_texture_usage(tex_) & GPU_TEXTURE_USAGE_HOST_READ, "The host-read usage flag must be specified up-front. Only textures which require data " - "reads should be flagged, allowing the backend to make certain optimiastions."); + "reads should be flagged, allowing the backend to make certain optimisations."); return tex->read(miplvl, data_format); } diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc index abf5d2dc4c0..d24dd6af95b 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.cc +++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc @@ -153,14 +153,9 @@ GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts_) return wrap(unwrap(verts_)->duplicate()); } -const void *GPU_vertbuf_read(GPUVertBuf *verts) +void GPU_vertbuf_read(GPUVertBuf *verts, void *data) { - return unwrap(verts)->read(); -} - -void *GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data) -{ - return unwrap(verts)->unmap(mapped_data); + unwrap(verts)->read(data); } void GPU_vertbuf_clear(GPUVertBuf *verts) diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh index f20f6caf6de..be8e4f0c185 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh @@ -94,8 +94,7 @@ class VertBuf { } virtual void update_sub(uint start, uint len, const void *data) = 0; - virtual const void *read() const = 0; - virtual void *unmap(const void *mapped_data) const = 0; + virtual void read(void *data) const = 0; protected: virtual void acquire_data() = 0; diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index c5202e597a7..2ba478d616b 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -155,8 +155,13 @@ static void gpu_viewport_textures_create(GPUViewport *viewport) /* Can be shared with GPUOffscreen. */ if (viewport->depth_tx == NULL) { - viewport->depth_tx = GPU_texture_create_2d_ex( - "dtxl_depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, usage, NULL); + /* Depth texture can be read back by gizmos #view3d_depths_create .*/ + viewport->depth_tx = GPU_texture_create_2d_ex("dtxl_depth", + UNPACK2(size), + 1, + GPU_DEPTH24_STENCIL8, + usage | GPU_TEXTURE_USAGE_HOST_READ, + NULL); if (GPU_clear_viewport_workaround()) { static int depth_clear = 0; GPU_texture_clear(viewport->depth_tx, GPU_DATA_UINT_24_8, &depth_clear); @@ -231,7 +236,7 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport, { /** * HACK(fclem): We copy the settings here to avoid use after free if an update frees the scene - * and the viewport stays cached (see T75443). But this means the OCIO curve-mapping caching + * and the viewport stays cached (see #75443). But this means the OCIO curve-mapping caching * (which is based on #CurveMap pointer address) cannot operate correctly and it will create * a different OCIO processor for each viewport. We try to only reallocate the curve-map copy * if needed to avoid unneeded cache invalidation. diff --git a/source/blender/gpu/metal/kernels/compute_texture_read.msl b/source/blender/gpu/metal/kernels/compute_texture_read.msl index 7b0760d7620..41d7b312dbd 100644 --- a/source/blender/gpu/metal/kernels/compute_texture_read.msl +++ b/source/blender/gpu/metal/kernels/compute_texture_read.msl @@ -77,6 +77,11 @@ template<> uint convert_type(float val) return uint(val * float(0xFFFFFFFFu)); } +template uint pack_depth_stencil(D depth, S stencil) +{ + return (((uint(depth)) << 8) & (~(0xFFu - 1))) | (uint(stencil) & (0xFFu - 1)); +} + struct TextureReadParams { int mip_index; int extent[3]; @@ -118,8 +123,14 @@ kernel void compute_texture_read(constant TextureReadParams ¶ms [[buffer(0)] /* Read data */ # if IS_DEPTH_FORMAT == 1 - output_data[index] = denormalize( + OUTPUT_DATA_TYPE value = denormalize( read_tex.sample(pixelSampler, float2(params.offset[0], params.offset[1]) + float2(xx, yy))); +# if IS_DEPTHSTENCIL_24_8 == 1 + /* Shift depth value into 24 bit region and mask out 8 bit stencil. + * NOTE: Stencil currently not read as no use cases exist for this. */ + value = pack_depth_stencil(value, 0); +# endif + output_data[index] = value; # else read_colour = read_tex.read(uint2(params.offset[0], params.offset[1]) + uint2(xx, yy)); # endif @@ -156,10 +167,16 @@ kernel void compute_texture_read(constant TextureReadParams ¶ms [[buffer(0)] /* Read data */ # if IS_DEPTH_FORMAT == 1 - output_data[index] = denormalize( + OUTPUT_DATA_TYPE value = denormalize( read_tex.sample(pixelSampler, float2(params.offset[0], params.offset[1]) + float2(xx, yy), uint(params.offset[2] + layer))); +# if IS_DEPTHSTENCIL_24_8 == 1 + /* Shift depth value into 24 bit region and mask out 8 bit stencil. + * NOTE: Stencil currently not read as no use cases exist for this. */ + value = pack_depth_stencil(value, 0); +# endif + output_data[index] = value; # else read_colour = read_tex.read(uint2(params.offset[0], params.offset[1]) + uint2(xx, yy), uint(params.offset[2] + layer)); diff --git a/source/blender/gpu/metal/mtl_batch.mm b/source/blender/gpu/metal/mtl_batch.mm index 13496e8ad6f..07aaa5cfe62 100644 --- a/source/blender/gpu/metal/mtl_batch.mm +++ b/source/blender/gpu/metal/mtl_batch.mm @@ -530,16 +530,16 @@ id MTLBatch::bind(uint v_first, uint v_count, uint i_fi /* Set SSBO-fetch-mode status uniforms. */ BLI_assert(active_shader_->uni_ssbo_input_prim_type_loc != -1); BLI_assert(active_shader_->uni_ssbo_input_vert_count_loc != -1); - GPU_shader_uniform_vector_int(reinterpret_cast(wrap(active_shader_)), - active_shader_->uni_ssbo_input_prim_type_loc, - 1, - 1, - (const int *)(&final_prim_type)); - GPU_shader_uniform_vector_int(reinterpret_cast(wrap(active_shader_)), - active_shader_->uni_ssbo_input_vert_count_loc, - 1, - 1, - (const int *)(&v_count)); + GPU_shader_uniform_int_ex(reinterpret_cast(wrap(active_shader_)), + active_shader_->uni_ssbo_input_prim_type_loc, + 1, + 1, + (const int *)(&final_prim_type)); + GPU_shader_uniform_int_ex(reinterpret_cast(wrap(active_shader_)), + active_shader_->uni_ssbo_input_vert_count_loc, + 1, + 1, + (const int *)(&v_count)); } /* Ensure Context Render Pipeline State is fully setup and ready to execute the draw. diff --git a/source/blender/gpu/metal/mtl_framebuffer.mm b/source/blender/gpu/metal/mtl_framebuffer.mm index dc8741e377b..9b334dd7166 100644 --- a/source/blender/gpu/metal/mtl_framebuffer.mm +++ b/source/blender/gpu/metal/mtl_framebuffer.mm @@ -109,7 +109,7 @@ void MTLFrameBuffer::bind(bool enabled_srgb) this->mark_dirty(); } enabled_srgb_ = enabled_srgb; - GPU_shader_set_framebuffer_srgb_target(enabled_srgb && srgb_); + Shader::set_framebuffer_srgb_target(enabled_srgb && srgb_); } /* Reset clear state on bind -- Clears and load/store ops are set after binding. */ diff --git a/source/blender/gpu/metal/mtl_immediate.mm b/source/blender/gpu/metal/mtl_immediate.mm index f0809e6e9d3..985b962cc99 100644 --- a/source/blender/gpu/metal/mtl_immediate.mm +++ b/source/blender/gpu/metal/mtl_immediate.mm @@ -248,16 +248,16 @@ void MTLImmediate::end() "ssbo_input_prim_type uniform location invalid!"); BLI_assert_msg(active_mtl_shader->uni_ssbo_input_vert_count_loc != -1, "ssbo_input_vert_count uniform location invalid!"); - GPU_shader_uniform_vector_int(reinterpret_cast(wrap(active_mtl_shader)), - active_mtl_shader->uni_ssbo_input_prim_type_loc, - 1, - 1, - (const int *)(&this->prim_type)); - GPU_shader_uniform_vector_int(reinterpret_cast(wrap(active_mtl_shader)), - active_mtl_shader->uni_ssbo_input_vert_count_loc, - 1, - 1, - (const int *)(&this->vertex_idx)); + GPU_shader_uniform_int_ex(reinterpret_cast(wrap(active_mtl_shader)), + active_mtl_shader->uni_ssbo_input_prim_type_loc, + 1, + 1, + (const int *)(&this->prim_type)); + GPU_shader_uniform_int_ex(reinterpret_cast(wrap(active_mtl_shader)), + active_mtl_shader->uni_ssbo_input_vert_count_loc, + 1, + 1, + (const int *)(&this->vertex_idx)); } MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type); diff --git a/source/blender/gpu/metal/mtl_index_buffer.hh b/source/blender/gpu/metal/mtl_index_buffer.hh index 702aa7f27d6..dd828598110 100644 --- a/source/blender/gpu/metal/mtl_index_buffer.hh +++ b/source/blender/gpu/metal/mtl_index_buffer.hh @@ -48,7 +48,7 @@ class MTLIndexBuf : public IndexBuf { ~MTLIndexBuf(); void bind_as_ssbo(uint32_t binding) override; - const uint32_t *read() const override; + void read(uint32_t *data) const override; void upload_data() override; void update_sub(uint32_t start, uint32_t len, const void *data) override; diff --git a/source/blender/gpu/metal/mtl_index_buffer.mm b/source/blender/gpu/metal/mtl_index_buffer.mm index cf921e43a4b..6a912983492 100644 --- a/source/blender/gpu/metal/mtl_index_buffer.mm +++ b/source/blender/gpu/metal/mtl_index_buffer.mm @@ -46,16 +46,13 @@ void MTLIndexBuf::bind_as_ssbo(uint32_t binding) MTL_LOG_WARNING("MTLIndexBuf::bind_as_ssbo not yet implemented!\n"); } -const uint32_t *MTLIndexBuf::read() const +void MTLIndexBuf::read(uint32_t *data) const { if (ibo_ != nullptr) { - - /* Return host pointer. */ - void *data = ibo_->get_host_ptr(); - return static_cast(data); + void *host_ptr = ibo_->get_host_ptr(); + memcpy(data, host_ptr, size_get()); } BLI_assert(false && "Index buffer not ready to be read."); - return nullptr; } void MTLIndexBuf::upload_data() diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 40ee7d5ac14..0b866456ffc 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -869,7 +869,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) #define GPU_ARB_shader_draw_parameters 1\n"; /* NOTE(Metal): textureGather appears to not function correctly on non-Apple-silicon GPUs. - * Manifests as selection outlines not showing up (T103412). Disable texture gather if + * Manifests as selection outlines not showing up (#103412). Disable texture gather if * not suitable for use. */ if (MTLBackend::get_capabilities().supports_texture_gather) { msl_defines_string += "#define GPU_ARB_texture_gather 1\n"; diff --git a/source/blender/gpu/metal/mtl_texture_util.mm b/source/blender/gpu/metal/mtl_texture_util.mm index cf7455368ca..09fb23b61fa 100644 --- a/source/blender/gpu/metal/mtl_texture_util.mm +++ b/source/blender/gpu/metal/mtl_texture_util.mm @@ -647,7 +647,9 @@ id gpu::MTLTexture::mtl_texture_read_impl( @"IS_DEPTH_FORMAT" : [NSNumber numberWithInt:((specialization_params.depth_format_mode > 0) ? 1 : 0)], @"DEPTH_SCALE_FACTOR" : [NSNumber numberWithLongLong:depth_scale_factor], - @"TEX_TYPE" : [NSNumber numberWithInt:((int)(texture_type))] + @"TEX_TYPE" : [NSNumber numberWithInt:((int)(texture_type))], + @"IS_DEPTHSTENCIL_24_8" : + [NSNumber numberWithInt:(specialization_params.depth_format_mode == 2) ? 1 : 0] }; /* Prepare shader library for conversion routine. */ diff --git a/source/blender/gpu/metal/mtl_vertex_buffer.hh b/source/blender/gpu/metal/mtl_vertex_buffer.hh index 54d2b7a86a3..056e2062ab1 100644 --- a/source/blender/gpu/metal/mtl_vertex_buffer.hh +++ b/source/blender/gpu/metal/mtl_vertex_buffer.hh @@ -56,8 +56,7 @@ class MTLVertBuf : public VertBuf { void update_sub(uint start, uint len, const void *data) override; - const void *read() const override; - void *unmap(const void *mapped_data) const override; + void read(void *data) const override; void wrap_handle(uint64_t handle) override; diff --git a/source/blender/gpu/metal/mtl_vertex_buffer.mm b/source/blender/gpu/metal/mtl_vertex_buffer.mm index 919eb1e3267..6114e1057c8 100644 --- a/source/blender/gpu/metal/mtl_vertex_buffer.mm +++ b/source/blender/gpu/metal/mtl_vertex_buffer.mm @@ -328,21 +328,12 @@ void MTLVertBuf::bind_as_texture(uint binding) GPU_texture_bind(buffer_texture_, binding); } -const void *MTLVertBuf::read() const +void MTLVertBuf::read(void *data) const { BLI_assert(vbo_ != nullptr); BLI_assert(usage_ != GPU_USAGE_DEVICE_ONLY); - void *return_ptr = vbo_->get_host_ptr(); - BLI_assert(return_ptr != nullptr); - - return return_ptr; -} - -void *MTLVertBuf::unmap(const void *mapped_data) const -{ - void *result = MEM_mallocN(alloc_size_, __func__); - memcpy(result, mapped_data, alloc_size_); - return result; + void *host_ptr = vbo_->get_host_ptr(); + memcpy(data, host_ptr, alloc_size_); } void MTLVertBuf::wrap_handle(uint64_t handle) diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index cba53188c05..21af443401f 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -255,7 +255,7 @@ static void detect_workarounds() * requirements. * * We use it as a target for glMapBuffer(Range) what is part of the OpenGL 4 API. So better - * disable it when we don't have an OpenGL4 context (See T77657) */ + * disable it when we don't have an OpenGL4 context (See #77657) */ if (!(epoxy_gl_version() >= 40)) { GLContext::base_instance_support = false; } @@ -275,12 +275,12 @@ static void detect_workarounds() GCaps.shader_draw_parameters_support = false; GCaps.broken_amd_driver = true; } - /* Compute shaders have some issues with those versions (see T94936). */ + /* Compute shaders have some issues with those versions (see #94936). */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) && (strstr(version, "4.5.14831") || strstr(version, "4.5.14760"))) { GCaps.compute_shader_support = false; } - /* We have issues with this specific renderer. (see T74024) */ + /* We have issues with this specific renderer. (see #74024) */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && (strstr(renderer, "AMD VERDE") || strstr(renderer, "AMD KAVERI") || strstr(renderer, "AMD TAHITI"))) { @@ -289,14 +289,14 @@ static void detect_workarounds() GCaps.shader_draw_parameters_support = false; GCaps.broken_amd_driver = true; } - /* Fix slowdown on this particular driver. (see T77641) */ + /* Fix slowdown on this particular driver. (see #77641) */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && strstr(version, "Mesa 19.3.4")) { GCaps.shader_image_load_store_support = false; GCaps.shader_draw_parameters_support = false; GCaps.broken_amd_driver = true; } - /* See T82856: AMD drivers since 20.11 running on a polaris architecture doesn't support the + /* See #82856: AMD drivers since 20.11 running on a polaris architecture doesn't support the * `GL_INT_2_10_10_10_REV` data type correctly. This data type is used to pack normals and flags. * The work around uses `GPU_RGBA16I`. In 22.?.? drivers this has been fixed for * polaris platform. Keeping legacy platforms around just in case. @@ -321,18 +321,18 @@ static void detect_workarounds() } /* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are * covered since they only support GL 4.4 on windows. - * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */ + * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see #76273) */ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && !(epoxy_gl_version() >= 45)) { GLContext::copy_image_support = false; } /* Special fix for these specific GPUs. - * Without this workaround, blender crashes on startup. (see T72098) */ + * Without this workaround, blender crashes on startup. (see #72098) */ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && (strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) { GCaps.mip_render_workaround = true; } - /* Intel Ivy Bridge GPU's seems to have buggy cube-map array support. (see T75943) */ + /* Intel Ivy Bridge GPU's seems to have buggy cube-map array support. (see #75943) */ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && (strstr(renderer, "HD Graphics 4000") || strstr(renderer, "HD Graphics 4400") || strstr(renderer, "HD Graphics 2500"))) { @@ -349,12 +349,12 @@ static void detect_workarounds() GLContext::base_instance_support = false; GCaps.use_main_context_workaround = true; } - /* Somehow fixes armature display issues (see T69743). */ + /* Somehow fixes armature display issues (see #69743). */ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY) && strstr(version, "Build 20.19.15.4285")) { GCaps.use_main_context_workaround = true; } - /* See T70187: merging vertices fail. This has been tested from `18.2.2` till `19.3.0~dev` + /* See #70187: merging vertices fail. This has been tested from `18.2.2` till `19.3.0~dev` * of the Mesa driver */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") || @@ -362,7 +362,7 @@ static void detect_workarounds() GLContext::unused_fb_slot_workaround = true; } /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather - * is reported to be supported but yield a compile error (see T55802). */ + * is reported to be supported but yield a compile error (see #55802). */ if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !(epoxy_gl_version() >= 40)) { GLContext::texture_gather_support = false; @@ -413,7 +413,7 @@ static void detect_workarounds() GLContext::generate_mipmap_workaround = true; } - /* Buggy interface query functions cause crashes when handling SSBOs (T93680) */ + /* Buggy interface query functions cause crashes when handling SSBOs (#93680) */ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY) && (strstr(renderer, "HD Graphics 4400") || strstr(renderer, "HD Graphics 4600"))) { GCaps.shader_storage_buffer_objects_support = false; diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index 28105e326ee..57db9809427 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -214,7 +214,7 @@ GLuint GLVaoCache::base_instance_vao_get(GPUBatch *batch, int i_first) base_instance_ = 0; } /** - * There seems to be a nasty bug when drawing using the same VAO reconfiguring (T71147). + * There seems to be a nasty bug when drawing using the same VAO reconfiguring (#71147). * We just use a throwaway VAO for that. Note that this is likely to degrade performance. */ #ifdef __APPLE__ diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index e94f5b66b97..cc7ecae5c55 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -280,7 +280,7 @@ void GLFrameBuffer::bind(bool enabled_srgb) else { glDisable(GL_FRAMEBUFFER_SRGB); } - GPU_shader_set_framebuffer_srgb_target(enabled_srgb && srgb_); + Shader::set_framebuffer_srgb_target(enabled_srgb && srgb_); } if (context_->active_fb != this) { diff --git a/source/blender/gpu/opengl/gl_immediate.cc b/source/blender/gpu/opengl/gl_immediate.cc index a332a2fbc7c..b0840e0bc22 100644 --- a/source/blender/gpu/opengl/gl_immediate.cc +++ b/source/blender/gpu/opengl/gl_immediate.cc @@ -153,7 +153,7 @@ void GLImmediate::end() glEnable(GL_PRIMITIVE_RESTART); #endif /* These lines are causing crash on startup on some old GPU + drivers. - * They are not required so just comment them. (T55722) */ + * They are not required so just comment them. (#55722) */ // glBindBuffer(GL_ARRAY_BUFFER, 0); // glBindVertexArray(0); } diff --git a/source/blender/gpu/opengl/gl_immediate.hh b/source/blender/gpu/opengl/gl_immediate.hh index 5c6ff510cef..91eda10551a 100644 --- a/source/blender/gpu/opengl/gl_immediate.hh +++ b/source/blender/gpu/opengl/gl_immediate.hh @@ -21,7 +21,7 @@ namespace blender::gpu { class GLImmediate : public Immediate { private: /* Use two buffers for strict and non-strict vertex count to - * avoid some huge driver slowdown (see T70922). + * avoid some huge driver slowdown (see #70922). * Use accessor functions to get / modify. */ struct { /** Opengl Handle for this buffer. */ diff --git a/source/blender/gpu/opengl/gl_index_buffer.cc b/source/blender/gpu/opengl/gl_index_buffer.cc index 566169182e3..2125583cd6b 100644 --- a/source/blender/gpu/opengl/gl_index_buffer.cc +++ b/source/blender/gpu/opengl/gl_index_buffer.cc @@ -46,12 +46,12 @@ void GLIndexBuf::bind_as_ssbo(uint binding) glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ibo_id_); } -const uint32_t *GLIndexBuf::read() const +void GLIndexBuf::read(uint32_t *data) const { BLI_assert(is_active()); - void *data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); - uint32_t *result = static_cast(data); - return result; + void *buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); + memcpy(data, buffer, size_get()); + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } bool GLIndexBuf::is_active() const diff --git a/source/blender/gpu/opengl/gl_index_buffer.hh b/source/blender/gpu/opengl/gl_index_buffer.hh index 78159db764c..eeb7aeeca88 100644 --- a/source/blender/gpu/opengl/gl_index_buffer.hh +++ b/source/blender/gpu/opengl/gl_index_buffer.hh @@ -29,7 +29,7 @@ class GLIndexBuf : public IndexBuf { void bind(); void bind_as_ssbo(uint binding) override; - const uint32_t *read() const override; + void read(uint32_t *data) const override; void *offset_ptr(uint additional_vertex_offset) const { diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 58407db015d..7fe0d878798 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -486,9 +486,9 @@ std::string GLShader::resources_declare(const ShaderCreateInfo &info) const } ss << ";\n"; } -#if 0 /* T95278: This is not be enough to prevent some compilers think it is recursive. */ +#if 0 /* #95278: This is not be enough to prevent some compilers think it is recursive. */ for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) { - /* T95278: Double macro to avoid some compilers think it is recursive. */ + /* #95278: Double macro to avoid some compilers think it is recursive. */ ss << "#define " << uniform.name << "_ " << uniform.name << "\n"; ss << "#define " << uniform.name << " (" << uniform.name << "_)\n"; } @@ -817,7 +817,7 @@ static char *glsl_patch_default_get() if (GLContext::texture_gather_support) { STR_CONCAT(patch, slen, "#extension GL_ARB_texture_gather: enable\n"); /* Some drivers don't agree on epoxy_has_gl_extension("GL_ARB_texture_gather") and the actual - * support in the shader so double check the preprocessor define (see T56544). */ + * support in the shader so double check the preprocessor define (see #56544). */ STR_CONCAT(patch, slen, "#ifdef GL_ARB_texture_gather\n"); STR_CONCAT(patch, slen, "# define GPU_ARB_texture_gather\n"); STR_CONCAT(patch, slen, "#endif\n"); diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc index ef97d74bf81..4b10780e551 100644 --- a/source/blender/gpu/opengl/gl_shader_interface.cc +++ b/source/blender/gpu/opengl/gl_shader_interface.cc @@ -371,13 +371,6 @@ GLShaderInterface::GLShaderInterface(GLuint program) builtin_blocks_[u] = (block != nullptr) ? block->binding : -1; } - /* Builtin Storage Buffers */ - for (int32_t u_int = 0; u_int < GPU_NUM_STORAGE_BUFFERS; u_int++) { - GPUStorageBufferBuiltin u = static_cast(u_int); - const ShaderInput *block = this->ssbo_get(builtin_storage_block_name(u)); - builtin_buffers_[u] = (block != nullptr) ? block->binding : -1; - } - MEM_freeN(uniforms_from_blocks); /* Resize name buffer to save some memory. */ @@ -550,13 +543,6 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI builtin_blocks_[u] = (block != nullptr) ? block->binding : -1; } - /* Builtin Storage Buffers */ - for (int32_t u_int = 0; u_int < GPU_NUM_STORAGE_BUFFERS; u_int++) { - GPUStorageBufferBuiltin u = static_cast(u_int); - const ShaderInput *block = this->ssbo_get(builtin_storage_block_name(u)); - builtin_buffers_[u] = (block != nullptr) ? block->binding : -1; - } - this->sort_inputs(); // this->debug_print(); diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 1410dad8a2f..424fbf702ea 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -353,7 +353,7 @@ void GLTexture::generate_mipmap() return; } - /* Some drivers have bugs when using #glGenerateMipmap with depth textures (see T56789). + /* Some drivers have bugs when using #glGenerateMipmap with depth textures (see #56789). * In this case we just create a complete texture with mipmaps manually without * down-sampling. You must initialize the texture levels using other methods like * #GPU_framebuffer_recursive_downsample(). */ @@ -448,7 +448,7 @@ void *GLTexture::read(int mip, eGPUDataFormat type) size_t texture_size = sample_len * sample_size; /* AMD Pro driver have a bug that write 8 bytes past buffer size - * if the texture is big. (see T66573) */ + * if the texture is big. (see #66573) */ void *data = MEM_mallocN(texture_size + 8, "GPU_texture_read"); GLenum gl_format = to_gl_data_format(format_); @@ -677,17 +677,17 @@ bool GLTexture::proxy_check(int mip) GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_OFFICIAL) || GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OFFICIAL)) { /* Some AMD drivers have a faulty `GL_PROXY_TEXTURE_..` check. - * (see T55888, T56185, T59351). + * (see #55888, #56185, #59351). * Checking with `GL_PROXY_TEXTURE_..` doesn't prevent `Out Of Memory` issue, * it just states that the OGL implementation can support the texture. * So we already manually check the maximum size and maximum number of layers. - * Same thing happens on Nvidia/macOS 10.15 (T78175). */ + * Same thing happens on Nvidia/macOS 10.15 (#78175). */ return true; } if ((type_ == GPU_TEXTURE_CUBE_ARRAY) && GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) { - /* Special fix for T79703. */ + /* Special fix for #79703. */ return true; } diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc index 9a6df38cb05..d5aa1141521 100644 --- a/source/blender/gpu/opengl/gl_vertex_array.cc +++ b/source/blender/gpu/opengl/gl_vertex_array.cc @@ -136,7 +136,7 @@ void GLVertArray::update_bindings(const GLuint vao, if (attr_mask & mask) { GLContext *ctx = GLContext::get(); /* This replaces glVertexAttrib4f(a, 0.0f, 0.0f, 0.0f, 1.0f); with a more modern style. - * Fix issues for some drivers (see T75069). */ + * Fix issues for some drivers (see #75069). */ glBindVertexBuffer(a, ctx->default_attr_vbo_, intptr_t(0), intptr_t(0)); glEnableVertexAttribArray(a); glVertexAttribFormat(a, 4, GL_FLOAT, GL_FALSE, 0); diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc index d186c2025b3..3a22480e190 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.cc +++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc @@ -125,18 +125,12 @@ void GLVertBuf::bind_as_texture(uint binding) GPU_texture_bind(buffer_texture_, binding); } -const void *GLVertBuf::read() const +void GLVertBuf::read(void *data) const { BLI_assert(is_active()); void *result = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); - return result; -} - -void *GLVertBuf::unmap(const void *mapped_data) const -{ - void *result = MEM_mallocN(vbo_size_, __func__); - memcpy(result, mapped_data, vbo_size_); - return result; + memcpy(data, result, size_used_get()); + glUnmapBuffer(GL_ARRAY_BUFFER); } void GLVertBuf::wrap_handle(uint64_t handle) diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh index deb966961f2..5137781309e 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.hh +++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh @@ -37,8 +37,7 @@ class GLVertBuf : public VertBuf { void update_sub(uint start, uint len, const void *data) override; - const void *read() const override; - void *unmap(const void *mapped_data) const override; + void read(void *data) const override; void wrap_handle(uint64_t handle) override; diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl index 2df6ebc33a0..0b764b954c8 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -169,7 +169,7 @@ mat4x4 scale(mat4x4 mat, vec3 scale); * * \note This code is about five times faster than the polar decomposition. * However, it gives un-expected results even with non-uniformly scaled matrices, - * see T46418 for an example. + * see #46418 for an example. * * \param A: Input matrix which is totally effective with `t = 0.0`. * \param B: Input matrix which is totally effective with `t = 1.0`. @@ -1059,7 +1059,7 @@ EulerXYZ to_euler(mat4x4 mat, const bool normalized) Quaternion normalized_to_quat_fast(mat3 mat) { - /* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */ + /* Caller must ensure matrices aren't negative for valid results, see: #24291, #94231. */ Quaternion q; /* Method outlined by Mike Day, ref: https://math.stackexchange.com/a/3183435/220949 @@ -1121,9 +1121,8 @@ Quaternion normalized_to_quat_fast(mat3 mat) } } else { - /* NOTE(@campbellbarton): A zero matrix will fall through to this block, - * needed so a zero scaled matrices to return a quaternion without rotation, see: T101848. - */ + /* NOTE(@ideasman42): A zero matrix will fall through to this block, + * needed so a zero scaled matrices to return a quaternion without rotation, see: #101848. */ float trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2]; float s = 2.0f * sqrt(trace); q.x = 0.25f * s; diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl deleted file mode 100644 index a43c1aa40cf..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl +++ /dev/null @@ -1,6 +0,0 @@ - -void main() -{ - gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); - finalColor = color; -} diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl index 38734d5bbaf..1f7482a1b51 100644 --- a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl @@ -228,6 +228,11 @@ void dF_branch(float fn, out vec2 result) result = vec2(0.0); } +void dF_branch_incomplete(float fn, out vec2 result) +{ + result = vec2(0.0); +} + #elif 0 /* TODO(@fclem): User Option? */ /* Fast derivatives */ vec3 dF_impl(vec3 v) @@ -266,6 +271,15 @@ vec3 dF_impl(vec3 v) result -= vec2((fn)); \ } +/* Used when the non-offset value is already computed elsewhere */ +# define dF_branch_incomplete(fn, result) \ + if (true) { \ + g_derivative_flag = 1; \ + result.x = (fn); \ + g_derivative_flag = -1; \ + result.y = (fn); \ + g_derivative_flag = 0; \ + } #endif /* TODO(fclem): Remove. */ diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl index 3690dd8d1d2..3b1dad24182 100644 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl @@ -1,16 +1,4 @@ -/* Values in GPU_shader.h. */ -#define GPU_KEYFRAME_SHAPE_DIAMOND (1u << 0) -#define GPU_KEYFRAME_SHAPE_CIRCLE (1u << 1) -#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1u << 2) -#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1u << 3) -#define GPU_KEYFRAME_SHAPE_INNER_DOT (1u << 4) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1u << 8) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1u << 9) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1u << 10) -#define GPU_KEYFRAME_SHAPE_SQUARE \ - (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) - const float diagonal_scale = sqrt(0.5); const float minmax_bias = 0.7; diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl index 78e8f40b25e..22599ca9fe5 100644 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl @@ -1,16 +1,4 @@ -/* Values in GPU_shader.h. */ -#define GPU_KEYFRAME_SHAPE_DIAMOND (1u << 0) -#define GPU_KEYFRAME_SHAPE_CIRCLE (1u << 1) -#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1u << 2) -#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1u << 3) -#define GPU_KEYFRAME_SHAPE_INNER_DOT (1u << 4) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1u << 8) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1u << 9) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1u << 10) -#define GPU_KEYFRAME_SHAPE_SQUARE \ - (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) - const float line_falloff = 1.0; const float circle_scale = sqrt(2.0 / 3.1416); const float square_scale = sqrt(0.5); diff --git a/source/blender/gpu/shaders/infos/gpu_shader_2D_widget_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_2D_widget_info.hh index 7a430717f85..4432c879be9 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_2D_widget_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_2D_widget_info.hh @@ -37,7 +37,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_2D_widget_base) .do_static_compilation(true) /* gl_InstanceID is supposed to be 0 if not drawing instances, but this seems * to be violated in some drivers. For example, macOS 10.15.4 and Intel Iris - * causes T78307 when using gl_InstanceID outside of instance. */ + * causes #78307 when using gl_InstanceID outside of instance. */ .define("widgetID", "0") .push_constant(Type::VEC4, "parameters", MAX_PARAM) .additional_info("gpu_shader_2D_widget_shared"); diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh index c71d7cf632a..e7a4705761f 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh @@ -7,16 +7,6 @@ #include "gpu_shader_create_info.hh" -GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_fixed_size_varying_color) - .vertex_in(0, Type::VEC3, "pos") - .vertex_in(1, Type::VEC4, "color") - .vertex_out(smooth_color_iface) - .fragment_out(0, Type::VEC4, "fragColor") - .push_constant(Type::MAT4, "ModelViewProjectionMatrix") - .vertex_source("gpu_shader_3D_point_fixed_size_varying_color_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") - .do_static_compilation(true); - GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_varying_size_varying_color) .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::VEC4, "color") diff --git a/source/blender/gpu/shaders/infos/gpu_shader_keyframe_shape_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_keyframe_shape_info.hh index f203a08eea5..eccbd50bf21 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_keyframe_shape_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_keyframe_shape_info.hh @@ -15,6 +15,7 @@ GPU_SHADER_INTERFACE_INFO(keyframe_shape_iface, "") .flat(Type::UINT, "finalFlags"); GPU_SHADER_CREATE_INFO(gpu_shader_keyframe_shape) + .typedef_source("GPU_shader_shared.h") .vertex_in(0, Type::VEC4, "color") .vertex_in(1, Type::VEC4, "outlineColor") .vertex_in(2, Type::VEC2, "pos") diff --git a/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh index bf4de62415d..1141e915c87 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh @@ -48,3 +48,9 @@ GPU_SHADER_CREATE_INFO(gpu_compute_ssbo_binding_test) .storage_buf(1, Qualifier::WRITE, "int", "data1[]") .compute_source("gpu_compute_dummy_test.glsl") .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(eevee_shadow_test) + .fragment_source("eevee_shadow_test.glsl") + .additional_info("gpu_shader_test") + .additional_info("eevee_shared") + .do_static_compilation(true); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl index d7c50e213e5..0d60dc2dfec 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_bump.glsl @@ -12,8 +12,13 @@ void differentiate_texco(vec4 v, out vec3 df) df = v.xyz + dF_impl(v.xyz); } -void node_bump( - float strength, float dist, float height, vec3 N, vec2 dHd, float invert, out vec3 result) +void node_bump(float strength, + float dist, + float height, + vec3 N, + vec2 height_xy, + float invert, + out vec3 result) { N = normalize(N); dist *= FrontFacing ? invert : -invert; @@ -29,6 +34,7 @@ void node_bump( /* Compute surface gradient and determinant. */ float det = dot(dPdx, Rx); + vec2 dHd = height_xy - vec2(height); vec3 surfgrad = dHd.x * Rx + dHd.y * Ry; strength = max(strength, 0.0); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index 0833809cc42..d5175f786db 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -149,7 +149,7 @@ void node_bsdf_principled(vec4 base_color, max(roughness, transmission_roughness); refraction_data.ior = ior; - /* Ref. T98190: Defines are optimizations for old compilers. + /* Ref. #98190: Defines are optimizations for old compilers. * Might become unnecessary with EEVEE-Next. */ if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat != 0.0) { #ifdef PRINCIPLED_CLEARCOAT diff --git a/source/blender/gpu/tests/gpu_shader_builtin_test.cc b/source/blender/gpu/tests/gpu_shader_builtin_test.cc index 567f1370f00..bb3f9f1a2ae 100644 --- a/source/blender/gpu/tests/gpu_shader_builtin_test.cc +++ b/source/blender/gpu/tests/gpu_shader_builtin_test.cc @@ -52,8 +52,6 @@ static void test_shader_builtin() GPU_SHADER_CFG_DEFAULT); test_compile_builtin_shader(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, GPU_SHADER_CFG_DEFAULT); - test_compile_builtin_shader(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR, - GPU_SHADER_CFG_DEFAULT); test_compile_builtin_shader(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR, GPU_SHADER_CFG_DEFAULT); test_compile_builtin_shader(GPU_SHADER_GPENCIL_STROKE, GPU_SHADER_CFG_DEFAULT); diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc index 00954c10c1a..ce1397f3327 100644 --- a/source/blender/gpu/tests/gpu_shader_test.cc +++ b/source/blender/gpu/tests/gpu_shader_test.cc @@ -47,7 +47,7 @@ static void test_gpu_shader_compute_2d() EXPECT_NE(texture, nullptr); GPU_shader_bind(shader); - GPU_texture_image_bind(texture, GPU_shader_get_texture_binding(shader, "img_output")); + GPU_texture_image_bind(texture, GPU_shader_get_sampler_binding(shader, "img_output")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, SIZE, 1); @@ -93,7 +93,7 @@ static void test_gpu_shader_compute_1d() EXPECT_NE(texture, nullptr); GPU_shader_bind(shader); - GPU_texture_image_bind(texture, GPU_shader_get_texture_binding(shader, "img_output")); + GPU_texture_image_bind(texture, GPU_shader_get_sampler_binding(shader, "img_output")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); @@ -142,7 +142,7 @@ static void test_gpu_shader_compute_vbo() GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DEVICE_ONLY); GPU_vertbuf_data_alloc(vbo, SIZE); - GPU_vertbuf_bind_as_ssbo(vbo, GPU_shader_get_ssbo(shader, "out_positions")); + GPU_vertbuf_bind_as_ssbo(vbo, GPU_shader_get_ssbo_binding(shader, "out_positions")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); @@ -151,8 +151,8 @@ static void test_gpu_shader_compute_vbo() GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); /* Download the vertex buffer. */ - const float *data = static_cast(GPU_vertbuf_read(vbo)); - ASSERT_NE(data, nullptr); + float data[SIZE * 4]; + GPU_vertbuf_read(vbo, data); for (int index = 0; index < SIZE; index++) { float expected_value = index; EXPECT_FLOAT_EQ(data[index * 4 + 0], expected_value); @@ -186,7 +186,7 @@ static void test_gpu_shader_compute_ibo() /* Construct IBO. */ GPUIndexBuf *ibo = GPU_indexbuf_build_on_device(SIZE); - GPU_indexbuf_bind_as_ssbo(ibo, GPU_shader_get_ssbo(shader, "out_indices")); + GPU_indexbuf_bind_as_ssbo(ibo, GPU_shader_get_ssbo_binding(shader, "out_indices")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); @@ -195,8 +195,8 @@ static void test_gpu_shader_compute_ibo() GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); /* Download the index buffer. */ - const uint32_t *data = GPU_indexbuf_read(ibo); - ASSERT_NE(data, nullptr); + uint32_t data[SIZE]; + GPU_indexbuf_read(ibo, data); for (int index = 0; index < SIZE; index++) { uint32_t expected = index; EXPECT_EQ(data[index], expected); @@ -228,7 +228,7 @@ static void test_gpu_shader_compute_ssbo() /* Construct IBO. */ GPUStorageBuf *ssbo = GPU_storagebuf_create_ex( SIZE * sizeof(uint32_t), nullptr, GPU_USAGE_DEVICE_ONLY, __func__); - GPU_storagebuf_bind(ssbo, GPU_shader_get_ssbo(shader, "out_indices")); + GPU_storagebuf_bind(ssbo, GPU_shader_get_ssbo_binding(shader, "out_indices")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); @@ -264,8 +264,8 @@ static void test_gpu_shader_ssbo_binding() EXPECT_NE(shader, nullptr); GPU_shader_bind(shader); - EXPECT_EQ(0, GPU_shader_get_ssbo(shader, "data0")); - EXPECT_EQ(1, GPU_shader_get_ssbo(shader, "data1")); + EXPECT_EQ(0, GPU_shader_get_ssbo_binding(shader, "data0")); + EXPECT_EQ(1, GPU_shader_get_ssbo_binding(shader, "data1")); /* Cleanup. */ GPU_shader_unbind(); @@ -402,7 +402,7 @@ static StringRef print_test_line(StringRefNull test_src, int64_t test_line) return ""; } -static void gpu_shader_lib_test(const char *test_src_name) +static void gpu_shader_lib_test(const char *test_src_name, const char *additional_info = nullptr) { using namespace shader; @@ -411,6 +411,9 @@ static void gpu_shader_lib_test(const char *test_src_name) ShaderCreateInfo create_info(test_src_name); create_info.fragment_source(test_src_name); create_info.additional_info("gpu_shader_test"); + if (additional_info) { + create_info.additional_info(additional_info); + } StringRefNull test_src = gpu_shader_dependency_get_source(test_src_name); @@ -484,4 +487,10 @@ static void test_gpu_math_lib() } GPU_TEST(gpu_math_lib) +static void test_eevee_lib() +{ + gpu_shader_lib_test("eevee_shadow_test.glsl", "eevee_shared"); +} +GPU_TEST(eevee_lib) + } // namespace blender::gpu::tests diff --git a/source/blender/gpu/vulkan/vk_index_buffer.cc b/source/blender/gpu/vulkan/vk_index_buffer.cc index ca3ce48dc64..70387bd0fce 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.cc +++ b/source/blender/gpu/vulkan/vk_index_buffer.cc @@ -17,9 +17,8 @@ void VKIndexBuffer::bind_as_ssbo(uint /*binding*/) { } -const uint32_t *VKIndexBuffer::read() const +void VKIndexBuffer::read(uint32_t * /*data*/) const { - return 0; } void VKIndexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/) diff --git a/source/blender/gpu/vulkan/vk_index_buffer.hh b/source/blender/gpu/vulkan/vk_index_buffer.hh index 94a584086e0..7586b49ff21 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.hh +++ b/source/blender/gpu/vulkan/vk_index_buffer.hh @@ -17,7 +17,7 @@ class VKIndexBuffer : public IndexBuf { void bind_as_ssbo(uint binding) override; - const uint32_t *read() const override; + void read(uint32_t *data) const override; void update_sub(uint start, uint len, const void *data) override; diff --git a/source/blender/gpu/vulkan/vk_memory.cc b/source/blender/gpu/vulkan/vk_memory.cc new file mode 100644 index 00000000000..e02ca0b014f --- /dev/null +++ b/source/blender/gpu/vulkan/vk_memory.cc @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#include "vk_memory.hh" + +#include "MEM_guardedalloc.h" + +namespace blender::gpu { + +#ifdef WITH_VULKAN_GUARDEDALLOC + +void *vk_memory_allocation(void *user_data, + size_t size, + size_t alignment, + VkSystemAllocationScope /*scope*/) +{ + const char *name = static_cast(const_cast(user_data)); + if (alignment) { + return MEM_mallocN_aligned(size, alignment, name); + } + return MEM_mallocN(size, name); +} + +void *vk_memory_reallocation(void *user_data, + void *original, + size_t size, + size_t /*alignment*/, + VkSystemAllocationScope /*scope*/) +{ + const char *name = static_cast(const_cast(user_data)); + return MEM_reallocN_id(original, size, name); +} + +void vk_memory_free(void * /*user_data*/, void *memory) +{ + MEM_freeN(memory); +} + +#endif + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_memory.hh b/source/blender/gpu/vulkan/vk_memory.hh new file mode 100644 index 00000000000..91802cb8193 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_memory.hh @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#ifdef __APPLE__ +# include +#else +# include +#endif + +namespace blender::gpu { + +/** + * `VK_ALLOCATION_CALLBACKS` initializes allocation callbacks for host allocations. + * The macro creates a local static variable with the name `vk_allocation_callbacks` + * that can be passed to vulkan API functions that expect + * `const VkAllocationCallbacks *pAllocator`. + * + * When Blender is compiled with `WITH_VULKAN_GUARDEDALLOC` this will use + * `MEM_guardedalloc` for host allocations that the driver does on behalf + * of blender. More internal allocations are still being allocated via the + * implemention inside the vulkan device driver. + * + * When `WITH_VULKAN_GUARDEDALLOC=Off` the memory allocation implemented + * in the vulkan device driver is used for both internal and application + * focussed memory operations. + */ + +#ifdef WITH_VULKAN_GUARDEDALLOC +void *vk_memory_allocation(void *user_data, + size_t size, + size_t alignment, + VkSystemAllocationScope scope); +void *vk_memory_reallocation( + void *user_data, void *original, size_t size, size_t alignment, VkSystemAllocationScope scope); +void vk_memory_free(void *user_data, void *memory); + +constexpr VkAllocationCallbacks vk_allocation_callbacks_init(const char *name) +{ + VkAllocationCallbacks callbacks = {}; + callbacks.pUserData = const_cast(name); + callbacks.pfnAllocation = vk_memory_allocation; + callbacks.pfnReallocation = vk_memory_reallocation; + callbacks.pfnFree = vk_memory_free; + callbacks.pfnInternalAllocation = nullptr; + callbacks.pfnInternalFree = nullptr; + return callbacks; +} + +# define VK_ALLOCATION_CALLBACKS \ + static constexpr const VkAllocationCallbacks vk_allocation_callbacks_ = \ + vk_allocation_callbacks_init(__func__); \ + static constexpr const VkAllocationCallbacks *vk_allocation_callbacks = &vk_allocation_callbacks_; +#else +# define VK_ALLOCATION_CALLBACKS \ + static constexpr const VkAllocationCallbacks *vk_allocation_callbacks = nullptr; +#endif + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index 17c06fb42e6..3f145bd4763 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -8,6 +8,7 @@ #include "vk_shader.hh" #include "vk_backend.hh" +#include "vk_memory.hh" #include "vk_shader_log.hh" #include "BLI_string_utils.h" @@ -559,6 +560,8 @@ Vector VKShader::compile_glsl_to_spirv(Span sources, void VKShader::build_shader_module(Span spirv_module, VkShaderModule *r_shader_module) { + VK_ALLOCATION_CALLBACKS; + VkShaderModuleCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; create_info.codeSize = spirv_module.size() * sizeof(uint32_t); @@ -567,7 +570,7 @@ void VKShader::build_shader_module(Span spirv_module, VkShaderModule * VKContext &context = *static_cast(VKContext::get()); VkResult result = vkCreateShaderModule( - context.device_get(), &create_info, nullptr, r_shader_module); + context.device_get(), &create_info, vk_allocation_callbacks, r_shader_module); if (result != VK_SUCCESS) { compilation_failed_ = true; *r_shader_module = VK_NULL_HANDLE; @@ -581,21 +584,23 @@ VKShader::VKShader(const char *name) : Shader(name) VKShader::~VKShader() { + VK_ALLOCATION_CALLBACKS + VkDevice device = context_->device_get(); if (vertex_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, vertex_module_, nullptr); + vkDestroyShaderModule(device, vertex_module_, vk_allocation_callbacks); vertex_module_ = VK_NULL_HANDLE; } if (geometry_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, geometry_module_, nullptr); + vkDestroyShaderModule(device, geometry_module_, vk_allocation_callbacks); geometry_module_ = VK_NULL_HANDLE; } if (fragment_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, fragment_module_, nullptr); + vkDestroyShaderModule(device, fragment_module_, vk_allocation_callbacks); fragment_module_ = VK_NULL_HANDLE; } if (compute_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, compute_module_, nullptr); + vkDestroyShaderModule(device, compute_module_, vk_allocation_callbacks); compute_module_ = VK_NULL_HANDLE; } } diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 3931c927499..f2326ddb134 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -32,14 +32,8 @@ void VKVertexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*dat { } -const void *VKVertexBuffer::read() const +void VKVertexBuffer::read(void * /*data*/) const { - return nullptr; -} - -void *VKVertexBuffer::unmap(const void * /*mapped_data*/) const -{ - return nullptr; } void VKVertexBuffer::acquire_data() diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.hh b/source/blender/gpu/vulkan/vk_vertex_buffer.hh index e4240787138..ebc3e105553 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.hh +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.hh @@ -20,8 +20,7 @@ class VKVertexBuffer : public VertBuf { void wrap_handle(uint64_t handle) override; void update_sub(uint start, uint len, const void *data) override; - const void *read() const override; - void *unmap(const void *mapped_data) const override; + void read(void *data) const override; protected: void acquire_data() override; diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index c467e48d21e..1560567ba8d 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -398,7 +398,7 @@ static void execute_posetree(struct Depsgraph *depsgraph, * local transform of the segment itself. */ copy_m4_m4(rootmat, pchan->parent->pose_mat); /* However, we do not want to get (i.e. reverse) parent's scale, - * as it generates T31008 kind of nasty bugs. */ + * as it generates #31008 kind of nasty bugs. */ normalize_m4(rootmat); } else { diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 06f7770d267..129b265f854 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -49,7 +49,7 @@ typedef struct DDSData { /* WARNING: Keep explicit value assignments here, * this file is included in areas where not all format defines are set * (e.g. intern/dds only get WITH_DDS, even if TIFF, HDR etc are also defined). - * See T46524. */ + * See #46524. */ /** #ImBuf.ftype flag, main image types. */ enum eImbFileType { diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 94c0555dcf0..a6edcc5977e 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -593,7 +593,7 @@ static int startffmpeg(struct anim *anim) anim->duration_in_frames = video_stream->nb_frames; /* Sanity check on the detected duration. This is to work around corruption like reported in - * T68091. */ + * #68091. */ if (frame_rate.den != 0 && pFormatCtx->duration > 0) { double stream_sec = anim->duration_in_frames * av_q2d(frame_rate); double container_sec = pFormatCtx->duration / (double)AV_TIME_BASE; @@ -927,7 +927,7 @@ static bool ffmpeg_pts_isect(int64_t pts_start, int64_t pts_end, int64_t pts_to_ static AVFrame *ffmpeg_frame_by_pts_get(struct anim *anim, int64_t pts_to_search) { /* NOTE: `frame->pts + frame->pkt_duration` does not always match pts of next frame. - * See footage from T86361. Here it is OK to use, because PTS must match current or backup frame. + * See footage from #86361. Here it is OK to use, because PTS must match current or backup frame. * If there is no current frame, return NULL. */ if (!anim->pFrame_complete) { @@ -986,7 +986,7 @@ static int ffmpeg_decode_video_frame(struct anim *anim) av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n"); /* Sometimes, decoder returns more than one frame per sent packet. Check if frames are available. - * This frames must be read, otherwise decoding will fail. See T91405. */ + * This frames must be read, otherwise decoding will fail. See #91405. */ anim->pFrame_complete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; if (anim->pFrame_complete) { av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE FROM CODEC BUFFER\n"); @@ -1175,8 +1175,7 @@ static void ffmpeg_decode_video_frame_scan(struct anim *anim, int64_t pts_to_sea /* Wrapper over av_seek_frame(), for formats that doesn't have its own read_seek() or * read_seek2() functions defined. When seeking in these formats, rule to seek to last * necessary I-frame is not honored. It is not even guaranteed that I-frame, that must be - * decoded will be read. See https://trac.ffmpeg.org/ticket/1607 and - * https://developer.blender.org/T86944. */ + * decoded will be read. See https://trac.ffmpeg.org/ticket/1607 & #86944. */ static int ffmpeg_generic_seek_workaround(struct anim *anim, int64_t *requested_pts, int64_t pts_to_search) @@ -1413,7 +1412,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ ffmpeg_decode_video_frame_scan(anim, pts_to_search); - /* Update resolution as it can change per-frame with WebM. See T100741 & T100081. */ + /* Update resolution as it can change per-frame with WebM. See #100741 & #100081. */ anim->x = anim->pCodecCtx->width; anim->y = anim->pCodecCtx->height; diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 9f14ca0d596..344dccfe919 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2054,7 +2054,7 @@ void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, if (STREQ(from_colorspace, to_colorspace)) { /* Because this function always takes a byte buffer and returns a float buffer, it must * always do byte-to-float conversion of some kind. To avoid threading overhead - * IMB_buffer_float_from_byte is used when color spaces are identical. See T51002. + * IMB_buffer_float_from_byte is used when color spaces are identical. See #51002. */ IMB_buffer_float_from_byte(float_buffer, byte_buffer, diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 29dfcc1b8f8..cec6913c211 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -205,9 +205,11 @@ static void test_endian_zbuf(struct ImBuf *ibuf) int len; int *zval; - if (BIG_LONG(1) == 1) { - return; - } + /* `BIG_LONG(1) == 1`, no change needed. */ +#ifdef __BIG_ENDIAN__ + return; +#endif + if (ibuf->zbuf == NULL) { return; } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index c17931827f7..e7d7ae973e4 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -1493,7 +1493,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa * like, MX or NZ, which is basically has structure of * * - * This is a bit silly, but see file from T35658. + * This is a bit silly, but see file from #35658. * * Here we do some magic to distinguish such cases. */ diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 42c19ce1a7e..6332310f43c 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -846,7 +846,7 @@ static void q_scale_float( * Should be comparable in speed to the ImBuf ..._fast functions at least * for byte-buffers. * - * NOTE: disabled, due to unacceptable inaccuracy and quality loss, see bug T18609 (ton) + * NOTE: disabled, due to unacceptable inaccuracy and quality loss, see bug #18609 (ton) */ static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy) { @@ -998,14 +998,14 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx) if (do_rect) { // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size); - BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug T26502. */ + BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug #26502. */ imb_freerectImBuf(ibuf); ibuf->mall |= IB_rect; ibuf->rect = (uint *)_newrect; } if (do_float) { // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size); - BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug T26502. */ + BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug #26502. */ imb_freerectfloatImBuf(ibuf); ibuf->mall |= IB_rectfloat; ibuf->rect_float = _newrectf; @@ -1140,14 +1140,14 @@ static ImBuf *scaledowny(struct ImBuf *ibuf, int newy) if (do_rect) { // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size); - BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug T26502. */ + BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug #26502. */ imb_freerectImBuf(ibuf); ibuf->mall |= IB_rect; ibuf->rect = (uint *)_newrect; } if (do_float) { // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size); - BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug T26502. */ + BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug #26502. */ imb_freerectfloatImBuf(ibuf); ibuf->mall |= IB_rectfloat; ibuf->rect_float = (float *)_newrectf; @@ -1196,7 +1196,7 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx) newrectf = _newrectf; /* Special case, copy all columns, needed since the scaling logic assumes there is at least - * two rows to interpolate between causing out of bounds read for 1px images, see T70356. */ + * two rows to interpolate between causing out of bounds read for 1px images, see #70356. */ if (UNLIKELY(ibuf->x == 1)) { if (do_rect) { for (y = ibuf->y; y > 0; y--) { @@ -1400,7 +1400,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) skipx = 4 * ibuf->x; /* Special case, copy all rows, needed since the scaling logic assumes there is at least - * two rows to interpolate between causing out of bounds read for 1px images, see T70356. */ + * two rows to interpolate between causing out of bounds read for 1px images, see #70356. */ if (UNLIKELY(ibuf->y == 1)) { if (do_rect) { for (y = newy; y > 0; y--) { @@ -1648,7 +1648,7 @@ bool IMB_scaleImBuf(struct ImBuf *ibuf, uint newx, uint newy) scalefast_Z_ImBuf(ibuf, newx, newy); /* try to scale common cases in a fast way */ - /* disabled, quality loss is unacceptable, see report T18609 (ton) */ + /* disabled, quality loss is unacceptable, see report #18609 (ton) */ if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) { return true; } diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index d535bd00501..29bac03654f 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -397,7 +397,7 @@ static ImBuf *thumb_create_ex(const char *file_path, if (img->x > tsize || img->y > tsize) { float scale = MIN2((float)tsize / (float)img->x, (float)tsize / (float)img->y); - /* Scaling down must never assign zero width/height, see: T89868. */ + /* Scaling down must never assign zero width/height, see: #89868. */ short ex = MAX2(1, (short)(img->x * scale)); short ey = MAX2(1, (short)(img->y * scale)); /* Save some time by only scaling byte buf */ diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index 77d42d905c7..e7eee7a43be 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -530,7 +530,7 @@ static void get_loop_normals(struct Mesh *mesh, normals.clear(); /* If all polygons are smooth shaded, and there are no custom normals, we don't need to export - * normals at all. This is also done by other software, see T71246. */ + * normals at all. This is also done by other software, see #71246. */ if (!has_flat_shaded_poly && !CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL) && (mesh->flag & ME_AUTOSMOOTH) == 0) { return; diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index 9e5182c53d4..baa03ca915b 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -420,7 +420,7 @@ static void read_custom_data_mcols(const std::string &iobject_full_name, /* The colors can go through two layers of indexing. Often the 'indices' * array doesn't do anything (i.e. indices[n] = n), but when it does, it's - * important. Blender 2.79 writes indices incorrectly (see T53745), which + * important. Blender 2.79 writes indices incorrectly (see #53745), which * is why we have to check for indices->size() > 0 */ bool use_dual_indexing = is_facevarying && indices->size() > 0; diff --git a/source/blender/io/alembic/intern/abc_reader_archive.h b/source/blender/io/alembic/intern/abc_reader_archive.h index 18f36922a1b..685da5af5dc 100644 --- a/source/blender/io/alembic/intern/abc_reader_archive.h +++ b/source/blender/io/alembic/intern/abc_reader_archive.h @@ -16,7 +16,7 @@ struct Main; namespace blender::io::alembic { /* Wrappers around input and output archives. The goal is to be able to use - * streams so that unicode paths work on Windows (T49112), and to make sure that + * streams so that unicode paths work on Windows (#49112), and to make sure that * the stream objects remain valid as long as the archives are open. */ diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index 11fb191b31c..e52b30cf5ea 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -202,7 +202,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) poly.totloop = face_size; /* Polygons are always assumed to be smooth-shaded. If the Alembic mesh should be flat-shaded, - * this is encoded in custom loop normals. See T71246. */ + * this is encoded in custom loop normals. See #71246. */ poly.flag |= ME_SMOOTH; /* NOTE: Alembic data is stored in the reverse order. */ @@ -215,7 +215,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) if (f > 0 && loop.v == last_vertex_index) { /* This face is invalid, as it has consecutive loops from the same vertex. This is caused - * by invalid geometry in the Alembic file, such as in T76514. */ + * by invalid geometry in the Alembic file, such as in #76514. */ seen_invalid_geometry = true; } last_vertex_index = loop.v; @@ -732,7 +732,7 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh, } else { /* If the face count changed (e.g. by triangulation), only read points. - * This prevents crash from T49813. + * This prevents crash from #49813. * TODO(kevin): perhaps find a better way to do this? */ if (face_counts->size() != existing_mesh->totpoly || face_indices->size() != existing_mesh->totloop) { @@ -1065,7 +1065,7 @@ Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh, } else { /* If the face count changed (e.g. by triangulation), only read points. - * This prevents crash from T49813. + * This prevents crash from #49813. * TODO(kevin): perhaps find a better way to do this? */ if (face_counts->size() != existing_mesh->totpoly || face_indices->size() != existing_mesh->totloop) { diff --git a/source/blender/io/avi/intern/avi_options.c b/source/blender/io/avi/intern/avi_options.c index 66b71c12e37..cd92db3ec82 100644 --- a/source/blender/io/avi/intern/avi_options.c +++ b/source/blender/io/avi/intern/avi_options.c @@ -84,7 +84,7 @@ AviError AVI_set_compress_option( case AVI_OPTION_QUALITY: for (i = 0; i < movie->header->Streams; i++) { if (avi_get_format_type(movie->streams[i].format) == FCC("vids")) { - movie->streams[i].sh.Quality = (*((int *)opt_data)) * 100; + movie->streams[i].sh.Quality = *((int *)opt_data) * 100; BLI_fseek(movie->fp, movie->offset_table[1 + i * 2 + 1], SEEK_SET); awrite(movie, movie->streams[i].sf, @@ -97,7 +97,7 @@ AviError AVI_set_compress_option( break; case AVI_OPTION_FRAMERATE: - useconds = (int)(1000000 / (*((double *)opt_data))); + useconds = (int)(1000000 / *((double *)opt_data)); if (useconds) { movie->header->MicroSecPerFrame = useconds; } diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp index 826d7864067..3d12abe3cda 100644 --- a/source/blender/io/collada/AnimationImporter.cpp +++ b/source/blender/io/collada/AnimationImporter.cpp @@ -1189,7 +1189,7 @@ void AnimationImporter::translate_Animations( for (uint j = 0; j < matBinds.getCount(); j++) { const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial(); const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]); - if (ef != nullptr) { /* can be NULL T28909. */ + if (ef != nullptr) { /* can be NULL #28909. */ Material *ma = uid_material_map[matuid]; if (!ma) { fprintf(stderr, @@ -1445,7 +1445,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type( for (uint j = 0; j < matBinds.getCount(); j++) { const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial(); const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]); - if (ef != nullptr) { /* can be NULL T28909. */ + if (ef != nullptr) { /* can be NULL #28909. */ const COLLADAFW::CommonEffectPointerArray &commonEffects = ef->getCommonEffects(); if (!commonEffects.empty()) { COLLADAFW::EffectCommon *efc = commonEffects[0]; diff --git a/source/blender/io/collada/DocumentExporter.cpp b/source/blender/io/collada/DocumentExporter.cpp index 07392e9c4ce..f70a551f075 100644 --- a/source/blender/io/collada/DocumentExporter.cpp +++ b/source/blender/io/collada/DocumentExporter.cpp @@ -109,7 +109,7 @@ extern "C" char build_hash[]; #include -char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) +const char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) { int layer_index = CustomData_get_layer_index(data, type); if (layer_index < 0) { @@ -119,7 +119,7 @@ char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int return data->layers[layer_index + n].name; } -char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) +const char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) { /* get the layer index of the active layer of type */ int layer_index = CustomData_get_active_layer_index(data, type); diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp index 5c1b9a1a294..49ed37ba976 100644 --- a/source/blender/io/collada/DocumentImporter.cpp +++ b/source/blender/io/collada/DocumentImporter.cpp @@ -265,7 +265,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = nullptr, Object *parob = nullptr) { - /* The split in T29246, root_map must point at actual root when + /* The split in #29246, root_map must point at actual root when * calculating bones in apply_curves_as_matrix. - actual root is the root node. * This has to do with inverse bind poses being world space * (the sources for skinned bones' rest-poses) and the way diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 64cefb168c8..b95c6110a0e 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -101,7 +101,7 @@ void GeometryExporter::operator()(Object *ob) createLooseEdgeList(ob, me, geom_id); - /* Only create Polylists if number of faces > 0 */ + /* Only create poly-lists if number of faces > 0. */ if (me->totface > 0) { /* XXX slow */ if (ob->totcol) { @@ -312,7 +312,7 @@ static bool collect_vertex_counts_per_poly(Mesh *me, return is_triangulated; } -std::string GeometryExporter::makeVertexColorSourceId(std::string &geom_id, char *layer_name) +std::string GeometryExporter::makeVertexColorSourceId(std::string &geom_id, const char *layer_name) { std::string result = getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + "-" + layer_name; @@ -390,7 +390,7 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, int map_index = 0; for (int a = 0; a < totlayer_mcol; a++) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, a); + const char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, a); COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, makeUrl(makeVertexColorSourceId(geom_id, layer_name)), (has_uvs) ? 3 : 2, /* all color layers have same index order */ @@ -489,7 +489,7 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) COLLADASW::FloatSourceF source(mSW); - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, a); + const char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, a); std::string layer_id = makeVertexColorSourceId(geom_id, layer_name); source.setId(layer_id); diff --git a/source/blender/io/collada/GeometryExporter.h b/source/blender/io/collada/GeometryExporter.h index 70e39f5bcd4..afaa6483108 100644 --- a/source/blender/io/collada/GeometryExporter.h +++ b/source/blender/io/collada/GeometryExporter.h @@ -87,7 +87,7 @@ class GeometryExporter : COLLADASW::LibraryGeometries { std::string getIdBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix = ""); - std::string makeVertexColorSourceId(std::string &geom_id, char *layer_name); + std::string makeVertexColorSourceId(std::string &geom_id, const char *layer_name); COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, diff --git a/source/blender/io/collada/InstanceWriter.cpp b/source/blender/io/collada/InstanceWriter.cpp index 76ada0be099..a0399bf638f 100644 --- a/source/blender/io/collada/InstanceWriter.cpp +++ b/source/blender/io/collada/InstanceWriter.cpp @@ -44,7 +44,7 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial &bind_materia int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); for (int b = 0; b < num_layers; b++) { if (!active_uv_only || b == active_uv_index) { - char *name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, b); + const char *name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 52eb852e1ed..288e208fe6c 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -562,15 +562,6 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len) CustomData_free(&mesh->edata, mesh->totedge); mesh->edata = edata; - - MutableSpan edges = mesh->edges_for_write(); - - /* set default flags */ - medge = &edges[mesh->totedge]; - for (int i = 0; i < len; i++, medge++) { - medge->flag = ME_EDGEDRAW; - } - mesh->totedge = totedge; } diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp index ae6bb9a541d..a71fbd50a2e 100644 --- a/source/blender/io/collada/collada_utils.cpp +++ b/source/blender/io/collada/collada_utils.cpp @@ -1076,7 +1076,7 @@ static std::string bc_get_active_uvlayer_name(Mesh *me) { int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (num_layers) { - char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2); + const char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2); if (layer_name) { return std::string(layer_name); } @@ -1101,7 +1101,7 @@ static std::string bc_get_uvlayer_name(Mesh *me, int layer) { int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (num_layers && layer < num_layers) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, layer); + const char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, layer); if (layer_name) { return std::string(layer_name); } diff --git a/source/blender/io/collada/collada_utils.h b/source/blender/io/collada/collada_utils.h index 2135277674a..dfa80552059 100644 --- a/source/blender/io/collada/collada_utils.h +++ b/source/blender/io/collada/collada_utils.h @@ -125,8 +125,8 @@ extern Mesh *bc_get_mesh_copy(BlenderContext &blender_context, extern Object *bc_get_assigned_armature(Object *ob); extern bool bc_has_object_type(LinkNode *export_set, short obtype); -extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); -extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); +extern const char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); +extern const char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); /** diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index b123eb251ab..ac9e22ee631 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -127,6 +127,8 @@ list(APPEND LIB ${BOOST_LIBRARIES} ${BOOST_PYTHON_LIBRARIES} ${PYTHON_LIBRARIES} + ${USD_LIBRARIES} + ${TBB_LIBRARIES} ) if(WITH_OPENVDB) @@ -141,27 +143,6 @@ endif() blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") -if(WIN32) - set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$:/WHOLEARCHIVE:${USD_DEBUG_LIB}>") - set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$:/WHOLEARCHIVE:${USD_RELEASE_LIB}>") - set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$:/WHOLEARCHIVE:${USD_RELEASE_LIB}>") - set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$:/WHOLEARCHIVE:${USD_RELEASE_LIB}>") -endif() - -# Source: -# https://github.com/PixarAnimationStudios/USD/blob/master/BUILDING.md#linking-whole-archives -if(WIN32) - target_link_libraries(bf_usd INTERFACE ${USD_LIBRARIES}) -elseif(APPLE) - target_link_libraries(bf_usd INTERFACE -Wl,-force_load ${USD_LIBRARIES}) -elseif(UNIX) - target_link_libraries(bf_usd INTERFACE "-Wl,--whole-archive ${USD_LIBRARIES} -Wl,--no-whole-archive ${TBB_LIBRARIES}") -else() - message(FATAL_ERROR "Unknown how to link USD with your compiler ${CMAKE_CXX_COMPILER_ID}") -endif() - -target_link_libraries(bf_usd INTERFACE ${TBB_LIBRARIES}) - if(WITH_GTESTS) set(TEST_SRC tests/usd_stage_creation_test.cc diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index 0d664811d12..3f8a21cc5ab 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -186,7 +186,7 @@ int OBJMesh::ith_smooth_group(const int poly_index) const void OBJMesh::ensure_mesh_normals() const { - /* Const cast can be removed when calculating face corner normals lazily is possible. */ + /* Constant cast can be removed when calculating face corner normals lazily is possible. */ BKE_mesh_calc_normals_split(const_cast(export_mesh_)); } @@ -194,8 +194,7 @@ void OBJMesh::calc_smooth_groups(const bool use_bitflags) { const bool *sharp_edges = static_cast( CustomData_get_layer_named(&export_mesh_->edata, CD_PROP_BOOL, "sharp_edge")); - poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.data(), - mesh_edges_.size(), + poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.size(), mesh_polys_.data(), mesh_polys_.size(), mesh_loops_.data(), diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index b90a0c99424..f0ae807b018 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -222,7 +222,7 @@ static void geom_add_polygon(Geometry *geom, else { geom->track_vertex_index(corner.vert_index); } - /* Ignore UV index, if the geometry does not have any UVs (T103212). */ + /* Ignore UV index, if the geometry does not have any UVs (#103212). */ if (got_uv && !global_vertices.uv_vertices.is_empty()) { corner.uv_vert_index += corner.uv_vert_index < 0 ? global_vertices.uv_vertices.size() : -1; if (corner.uv_vert_index < 0 || corner.uv_vert_index >= global_vertices.uv_vertices.size()) { @@ -235,7 +235,7 @@ static void geom_add_polygon(Geometry *geom, } /* Ignore corner normal index, if the geometry does not have any normals. * Some obj files out there do have face definitions that refer to normal indices, - * without any normals being present (T98782). */ + * without any normals being present (#98782). */ if (got_normal && !global_vertices.vertex_normals.is_empty()) { corner.vertex_normal_index += corner.vertex_normal_index < 0 ? global_vertices.vertex_normals.size() : @@ -252,7 +252,7 @@ static void geom_add_polygon(Geometry *geom, geom->face_corners_.append(corner); curr_face.corner_count_++; - /* Some files contain extra stuff per face (e.g. 4 indices); skip any remainder (T103441). */ + /* Some files contain extra stuff per face (e.g. 4 indices); skip any remainder (#103441). */ p = drop_non_whitespace(p, end); /* Skip whitespace to get to the next face corner. */ p = drop_whitespace(p, end); @@ -767,7 +767,7 @@ Span OBJParser::mtl_libraries() const void OBJParser::add_mtl_library(StringRef path) { - /* Remove any quotes from start and end (T67266, T97794). */ + /* Remove any quotes from start and end (#67266, #97794). */ if (path.size() > 2 && path.startswith("\"") && path.endswith("\"")) { path = path.drop_prefix(1).drop_suffix(1); } @@ -783,7 +783,7 @@ void OBJParser::add_default_mtl_library() * into candidate .mtl files to search through. This is not technically following the * spec, but the old python importer was doing it, and there are user files out there * that contain "mtllib bar.mtl" for a foo.obj, and depend on finding materials - * from foo.mtl (see T97757). */ + * from foo.mtl (see #97757). */ char mtl_file_path[FILE_MAX]; BLI_strncpy(mtl_file_path, import_params_.filepath, sizeof(mtl_file_path)); BLI_path_extension_replace(mtl_file_path, sizeof(mtl_file_path), ".mtl"); @@ -855,7 +855,7 @@ void MTLParser::parse_and_store(Map> &r_mat parse_float(p, end, 1.0f, material->alpha); } else if (parse_keyword(p, end, "illum")) { - /* Some files incorrectly use a float (T60135). */ + /* Some files incorrectly use a float (#60135). */ float val; parse_float(p, end, 1.0f, val); material->illum_mode = val; diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 794d307730c..3c9d5663a43 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -286,7 +286,7 @@ void MeshFromGeometry::create_uv_verts(Mesh *mesh) added_uv = true; } else { - uv_map.span[tot_loop_idx] = {0.f, 0.f}; + uv_map.span[tot_loop_idx] = {0.0f, 0.0f}; } tot_loop_idx++; } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index a0f5448a003..a5fea870a9b 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -818,7 +818,7 @@ enum { * RESET_NEVER * * \warning This should not be cleared on existing data. - * If support for this is needed, see T88026 as this flag controls memory ownership + * If support for this is needed, see #88026 as this flag controls memory ownership * of physics *shared* pointers. */ LIB_TAG_COPIED_ON_WRITE = 1 << 12, diff --git a/source/blender/makesdna/DNA_ID_enums.h b/source/blender/makesdna/DNA_ID_enums.h index 5999af8bf5c..94ab24511d8 100644 --- a/source/blender/makesdna/DNA_ID_enums.h +++ b/source/blender/makesdna/DNA_ID_enums.h @@ -46,7 +46,7 @@ typedef enum ID_Type { ID_LI = MAKE_ID2('L', 'I'), /* Library */ ID_OB = MAKE_ID2('O', 'B'), /* Object */ ID_ME = MAKE_ID2('M', 'E'), /* Mesh */ - ID_CU_LEGACY = MAKE_ID2('C', 'U'), /* Curve. ID_CV should be used in the future (see T95355). */ + ID_CU_LEGACY = MAKE_ID2('C', 'U'), /* Curve. ID_CV should be used in the future (see #95355). */ ID_MB = MAKE_ID2('M', 'B'), /* MetaBall */ ID_MA = MAKE_ID2('M', 'A'), /* Material */ ID_TE = MAKE_ID2('T', 'E'), /* Tex (Texture) */ diff --git a/source/blender/makesdna/DNA_brush_defaults.h b/source/blender/makesdna/DNA_brush_defaults.h index 6e88275672a..562632e05cd 100644 --- a/source/blender/makesdna/DNA_brush_defaults.h +++ b/source/blender/makesdna/DNA_brush_defaults.h @@ -94,7 +94,7 @@ .automasking_cavity_blur_steps = 0,\ .automasking_cavity_factor = 1.0f,\ \ - /* A kernel radius of 1 has almost no effect (T63233). */ \ + /* A kernel radius of 1 has almost no effect (#63233). */ \ .blur_kernel_radius = 2, \ \ .mtex = _DNA_DEFAULT_MTex, \ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index a415122579e..fd72a58fe14 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -10,6 +10,7 @@ #include "DNA_ID.h" #include "DNA_brush_enums.h" #include "DNA_curve_types.h" +#include "DNA_defs.h" #include "DNA_texture_types.h" /* for MTex */ #ifdef __cplusplus @@ -165,6 +166,8 @@ typedef struct BrushCurvesSculptSettings { } BrushCurvesSculptSettings; typedef struct Brush { + DNA_DEFINE_CXX_METHODS(Brush) + ID id; struct BrushClone clone; diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index 3ee2ba2797d..cef5f70b732 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -197,6 +197,7 @@ typedef struct Curves { /** #Curves.flag */ enum { HA_DS_EXPAND = (1 << 0), + CV_SCULPT_COLLISION_ENABLED = (1 << 1), }; /** #Curves.symmetry */ diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 3b4a52eb29a..4f748fe6828 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -39,7 +39,6 @@ typedef struct MEdge { enum { /** Deprecated selection status. Now stored in ".select_edge" attribute. */ /* SELECT = (1 << 0), */ - ME_EDGEDRAW = (1 << 1), ME_SEAM = (1 << 2), /** Deprecated hide status. Now stored in ".hide_edge" attribute. */ /* ME_HIDE = (1 << 4), */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 8f9ae28b441..9e4505ca529 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -282,6 +282,10 @@ typedef enum eNodeSocketFlag { * type is obvious and the name takes up too much space. */ SOCK_HIDE_LABEL = (1 << 12), + /** + * Only used for geometry nodes. Don't show the socket value in the modifier interface. + */ + SOCK_HIDE_IN_MODIFIER = (1 << 13), } eNodeSocketFlag; typedef struct bNode { @@ -961,7 +965,7 @@ typedef struct NodeScriptDict { typedef struct NodeGlare { char quality, type, iter; /* XXX angle is only kept for backward/forward compatibility, - * was used for two different things, see T50736. */ + * was used for two different things, see #50736. */ char angle DNA_DEPRECATED, _pad0, size, star_45, streaks; float colmod, mix, threshold, fade; float angle_ofs; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 889f154c1b8..29d74ba2046 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -497,7 +497,7 @@ typedef struct ObHook { enum { OB_EMPTY = 0, OB_MESH = 1, - /** Curve object is still used but replaced by "Curves" for the future (see T95355). */ + /** Curve object is still used but replaced by "Curves" for the future (see #95355). */ OB_CURVES_LEGACY = 2, OB_SURF = 3, OB_FONT = 4, diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 75410716e22..445d75406f1 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -113,7 +113,7 @@ typedef struct ParticleData { * Particles can die unnaturally (collision). * * \note Particles die on this frame, be sure to add 1 when clamping the lifetime of particles - * to inclusive ranges such as the scenes end frame. See: T68290. + * to inclusive ranges such as the scenes end frame. See: #68290. */ float dietime; diff --git a/source/blender/makesdna/DNA_pointcache_types.h b/source/blender/makesdna/DNA_pointcache_types.h index 1133237199b..2a63482c6b9 100644 --- a/source/blender/makesdna/DNA_pointcache_types.h +++ b/source/blender/makesdna/DNA_pointcache_types.h @@ -126,7 +126,7 @@ enum { // PTCACHE_BAKE_EDIT = 1 << 4, // PTCACHE_BAKE_EDIT_ACTIVE = 1 << 5, PTCACHE_DISK_CACHE = 1 << 6, - /* removed since 2.64 - T30974, could be added back in a more useful way */ + /* removed since 2.64 - #30974, could be added back in a more useful way */ // PTCACHE_QUICK_CACHE = 1 << 7, PTCACHE_FRAMES_SKIPPED = 1 << 8, PTCACHE_EXTERNAL = 1 << 9, diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a17d70a10a0..ca1d878110f 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -9,12 +9,12 @@ #include "DNA_defs.h" -/* XXX(@campbellbarton): temp feature. */ +/* XXX(@ideasman42): temp feature. */ #define DURIAN_CAMERA_SWITCH /** * Check for cyclic set-scene. - * Libraries can cause this case which is normally prevented, see (T42009). + * Libraries can cause this case which is normally prevented, see (#42009). */ #define USE_SETSCENE_CHECK @@ -793,6 +793,8 @@ typedef struct RenderData { float simplify_particles; float simplify_particles_render; float simplify_volumes; + float simplify_shadows; + float simplify_shadows_render; /** Freestyle line thickness options. */ int line_thickness_mode; @@ -1829,6 +1831,8 @@ typedef struct SceneEEVEE { int shadow_method DNA_DEPRECATED; int shadow_cube_size; int shadow_cascade_size; + int shadow_pool_size; + char _pad[4]; struct LightCache *light_cache DNA_DEPRECATED; struct LightCache *light_cache_data; @@ -2157,7 +2161,7 @@ extern const char *RE_engine_id_CYCLES; /** \name Scene Defines * \{ */ -/* Note that much higher max-frames give imprecise sub-frames, see: T46859. */ +/* Note that much higher max-frames give imprecise sub-frames, see: #46859. */ /* Current precision is 16 for the sub-frames closer to MAXFRAME. */ /* For general use. */ @@ -2429,6 +2433,7 @@ typedef enum ePaintFlags { * (for now just a duplicate of sculpt symmetry flags). */ typedef enum ePaintSymmetryFlags { + PAINT_SYMM_NONE = 0, PAINT_SYMM_X = (1 << 0), PAINT_SYMM_Y = (1 << 1), PAINT_SYMM_Z = (1 << 2), @@ -2438,6 +2443,13 @@ typedef enum ePaintSymmetryFlags { PAINT_TILE_Z = (1 << 6), } ePaintSymmetryFlags; ENUM_OPERATORS(ePaintSymmetryFlags, PAINT_TILE_Z); +#ifdef __cplusplus +inline ePaintSymmetryFlags operator++(ePaintSymmetryFlags &flags, int) +{ + flags = ePaintSymmetryFlags(char(flags) + 1); + return flags; +} +#endif #define PAINT_SYMM_AXIS_ALL (PAINT_SYMM_X | PAINT_SYMM_Y | PAINT_SYMM_Z) @@ -2694,6 +2706,7 @@ enum { SCE_EEVEE_OVERSCAN = (1 << 21), SCE_EEVEE_DOF_HQ_SLIGHT_FOCUS = (1 << 22), SCE_EEVEE_DOF_JITTER = (1 << 23), + SCE_EEVEE_SHADOW_ENABLED = (1 << 24), }; /** #SceneEEVEE.shadow_method */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 54edf795e6c..a4cb6723a8d 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -100,7 +100,7 @@ enum { /** * Used to mark a space as active but "overlapped" by temporary full-screen spaces. Without this * we wouldn't be able to restore the correct active space after closing temp full-screens - * reliably if the same space type is opened twice in a full-screen stack (see T19296). We don't + * reliably if the same space type is opened twice in a full-screen stack (see #19296). We don't * actually open the same space twice, we have to pretend it is by managing area order carefully. */ SPACE_FLAG_TYPE_WAS_ACTIVE = (1 << 1), diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index d33272183bb..bdf2210deae 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -354,7 +354,8 @@ typedef struct ThemeSpace { unsigned char path_before[4], path_after[4]; unsigned char path_keyframe_before[4], path_keyframe_after[4]; unsigned char camera_path[4]; - unsigned char _pad1[6]; + unsigned char camera_passepartout[4]; + unsigned char _pad1[2]; unsigned char gp_vertex_size; unsigned char gp_vertex[4], gp_vertex_select[4]; @@ -653,7 +654,8 @@ typedef struct UserDef_Experimental { char enable_eevee_next; char use_sculpt_texture_paint; char enable_workbench_next; - char _pad[7]; + char use_new_volume_nodes; + char _pad[6]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 4c5ba4c43f8..f6ee3d6e2dd 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -400,7 +400,7 @@ enum { /*#define RV3D_IS_GAME_ENGINE (1 << 5) */ /* UNUSED */ /** * Disable Z-buffer offset, skip calls to #ED_view3d_polygon_offset. - * Use when precise surface depth is needed and picking bias isn't, see T45434). + * Use when precise surface depth is needed and picking bias isn't, see #45434). */ #define RV3D_ZOFFSET_DISABLED 64 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 49099d921c4..e6f48c2da46 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -292,7 +292,7 @@ typedef struct wmWindow { /** * Enable when the drag was handled, * to avoid mouse-motion continually triggering drag events which are not handled - * but add overhead to gizmo handling (for example), see T87511. + * but add overhead to gizmo handling (for example), see #87511. */ char event_queue_check_drag_handled; @@ -620,7 +620,7 @@ enum { * This difference can be important because previous settings may be used, * even with #PROP_SKIP_SAVE the repeat last operator will use the previous settings. * Unlike #OP_IS_REPEAT the selection (and context generally) may be different each time. - * See T60777 for an example of when this is needed. + * See #60777 for an example of when this is needed. */ OP_IS_REPEAT_LAST = (1 << 1), diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index b9556a411cf..a28c159722f 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -86,7 +86,7 @@ typedef enum PropertyUnit { * Use values besides #PROP_SCALE_LINEAR * so the movement of the mouse doesn't map linearly to the value of the slider. * - * For some settings it's useful to space motion in a non-linear way, see T77868. + * For some settings it's useful to space motion in a non-linear way, see #77868. * * NOTE: The scale types are available for all float sliders. * For integer sliders they are only available if they use the visible value bar. @@ -234,7 +234,7 @@ typedef enum PropertyFlag { * Use for... * - pointers: in the UI and python so unsetting or setting to None won't work. * - strings: so our internal generated get/length/set - * functions know to do NULL checks before access T30865. + * functions know to do NULL checks before access #30865. */ PROP_NEVER_NULL = (1 << 18), /** diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 49c388a6cbf..c4509fb44dc 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -577,7 +577,7 @@ IDProperty **rna_ID_idprops(PointerRNA *ptr) int rna_ID_is_runtime_editable(PointerRNA *ptr, const char **r_info) { ID *id = (ID *)ptr->data; - /* TODO: This should be abstracted in a BKE function or define, somewhat related to T88555. */ + /* TODO: This should be abstracted in a BKE function or define, somewhat related to #88555. */ if (id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_TEMP_MAIN | LIB_TAG_LOCALIZED | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_COPIED_ON_WRITE)) { *r_info = @@ -592,7 +592,7 @@ int rna_ID_is_runtime_editable(PointerRNA *ptr, const char **r_info) bool rna_ID_is_runtime_get(PointerRNA *ptr) { ID *id = (ID *)ptr->data; - /* TODO: This should be abstracted in a BKE function or define, somewhat related to T88555. */ + /* TODO: This should be abstracted in a BKE function or define, somewhat related to #88555. */ if (id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_TEMP_MAIN | LIB_TAG_LOCALIZED | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_COPIED_ON_WRITE)) { return true; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index d6d7ae359d6..ca919224b25 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2094,7 +2094,7 @@ static void rna_property_update( } #if 1 - /* TODO(@campbellbarton): Should eventually be replaced entirely by message bus (below) + /* TODO(@ideasman42): Should eventually be replaced entirely by message bus (below) * for now keep since COW, bugs are hard to track when we have other missing updates. */ if (prop->noteflag) { WM_main_add_notifier(prop->noteflag, ptr->owner_id); @@ -2130,7 +2130,7 @@ static void rna_property_update( * * So editing custom properties only causes updates in the UI, * keep this exception because it happens to be useful for driving settings. - * Python developers on the other hand will need to manually 'update_tag', see: T74000. */ + * Python developers on the other hand will need to manually 'update_tag', see: #74000. */ DEG_id_tag_update(ptr->owner_id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_PARAMETERS); @@ -5942,7 +5942,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, case PROP_STRING: { const char *defvalue = ((StringPropertyRNA *)parm)->defaultvalue; if (defvalue && defvalue[0]) { - /* causes bug T29988, possibly this is only correct for thick wrapped + /* Causes bug #29988, possibly this is only correct for thick wrapped * need to look further into it - campbell */ #if 0 BLI_strncpy(data, defvalue, size); diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 14f4a82c62b..79d6ba0e442 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -876,7 +876,7 @@ static void rna_def_action(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "markers", NULL); RNA_def_property_struct_type(prop, "TimelineMarker"); /* Use lib exception so the list isn't grayed out; - * adding/removing is still banned though, see T45689. */ + * adding/removing is still banned though, see #45689. */ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); RNA_def_property_ui_text( prop, "Pose Markers", "Markers specific to this action, for labeling poses"); diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 72cf9d57c7b..e9068010c48 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -332,7 +332,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA * WM_main_add_notifier(NC_LINESTYLE, linestyle); break; } - /* ColorRamp for particle display is owned by the object (see T54422) */ + /* ColorRamp for particle display is owned by the object (see #54422) */ case ID_OB: case ID_PA: { ParticleSettings *part = (ParticleSettings *)ptr->owner_id; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index d6ec43ba39d..ab58f9ae884 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1073,19 +1073,19 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) }; static const EnumPropertyItem prop_align_y_items[] = { + {CU_ALIGN_Y_TOP, "TOP", ICON_ALIGN_TOP, "Top", "Align text to the top"}, {CU_ALIGN_Y_TOP_BASELINE, "TOP_BASELINE", ICON_ALIGN_TOP, - "Top Base-Line", - "Align to top but use the base-line of the text"}, - {CU_ALIGN_Y_TOP, "TOP", ICON_ALIGN_TOP, "Top", "Align text to the top"}, - {CU_ALIGN_Y_CENTER, "CENTER", ICON_ALIGN_MIDDLE, "Center", "Align text to the middle"}, - {CU_ALIGN_Y_BOTTOM, "BOTTOM", ICON_ALIGN_BOTTOM, "Bottom", "Align text to the bottom"}, + "Top Baseline", + "Align text to the top line's baseline"}, + {CU_ALIGN_Y_CENTER, "CENTER", ICON_ALIGN_MIDDLE, "Middle", "Align text to the middle"}, {CU_ALIGN_Y_BOTTOM_BASELINE, "BOTTOM_BASELINE", ICON_ALIGN_BOTTOM, - "Bottom Base-Line", - "Align text to the bottom but use the base-line of the text"}, + "Bottom Baseline", + "Align text to the bottom line's baseline"}, + {CU_ALIGN_Y_BOTTOM, "BOTTOM", ICON_ALIGN_BOTTOM, "Bottom", "Align text to the bottom"}, {0, NULL, 0, NULL, NULL}, }; @@ -1109,14 +1109,14 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "spacemode"); RNA_def_property_enum_items(prop, prop_align_items); RNA_def_property_ui_text( - prop, "Text Horizontal Align", "Text horizontal align from the object center"); + prop, "Horizontal Alignment", "Text horizontal alignment from the object center"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "align_y", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "align_y"); RNA_def_property_enum_items(prop, prop_align_y_items); RNA_def_property_ui_text( - prop, "Text Vertical Align", "Text vertical align from the object center"); + prop, "Vertical Alignment", "Text vertical alignment from the object center"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "overflow", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c index 7560e1a60cb..24b3de95123 100644 --- a/source/blender/makesrna/intern/rna_curves.c +++ b/source/blender/makesrna/intern/rna_curves.c @@ -275,7 +275,7 @@ static void rna_def_curves_point(BlenderRNA *brna) prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_int_funcs(prop, "rna_CurvePoint_index_get", NULL, NULL); - RNA_def_property_ui_text(prop, "Index", "Index of this points"); + RNA_def_property_ui_text(prop, "Index", "Index of this point"); } /* Defines a read-only vector type since normals can not be modified manually. */ @@ -453,6 +453,13 @@ static void rna_def_curves(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, 0, "rna_Curves_update_data"); + prop = RNA_def_property(srna, "use_sculpt_collision", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CV_SCULPT_COLLISION_ENABLED); + RNA_def_property_ui_text( + prop, "Use Sculpt Collision", "Enable collision with the surface while sculpting"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Curves_update_draw"); + /* attributes */ rna_def_attributes_common(srna); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index b7856794da2..58acc49aefe 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -4439,7 +4439,7 @@ void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropert if (tot == 0) { *items = MEM_callocN(sizeof(EnumPropertyItem[8]), __func__); - /* Ensure we get crashes on missing calls to 'RNA_enum_item_end', see T74227. */ + /* Ensure we get crashes on missing calls to 'RNA_enum_item_end', see #74227. */ #ifdef DEBUG memset(*items, 0xff, sizeof(EnumPropertyItem[8])); #endif diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c index 9af76de2a2b..1ff41e3637b 100644 --- a/source/blender/makesrna/intern/rna_depsgraph.c +++ b/source/blender/makesrna/intern/rna_depsgraph.c @@ -48,7 +48,7 @@ typedef struct RNA_DepsgraphIterator { # ifdef WITH_PYTHON /** * Store the Python instance so the #BPy_StructRNA can be set as invalid iteration is completed. - * Otherwise accessing from Python (console auto-complete for e.g.) crashes, see: T100286. */ + * Otherwise accessing from Python (console auto-complete for e.g.) crashes, see: #100286. */ void *py_instance; # endif } RNA_DepsgraphIterator; @@ -348,7 +348,7 @@ static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter) * Contains extra information about duplicator and persistent ID. */ -/* XXX Ugly python seems to query next item of an iterator before using current one (see T57558). +/* XXX Ugly python seems to query next item of an iterator before using current one (see #57558). * This forces us to use that nasty ping-pong game between two sets of iterator data, * so that previous one remains valid memory for python to access to. Yuck. */ diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index e19c569bca0..f92b137d3ae 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -714,7 +714,7 @@ static void rna_FModifier_start_frame_range(PointerRNA *UNUSED(ptr), // FModifier *fcm = (FModifier *)ptr->data; /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that, - * or else it becomes tricky to adjust the range, see: T36844. + * or else it becomes tricky to adjust the range, see: #36844. * * NOTE: we do not set soft-limits on lower bounds, as it's too confusing when you * can't easily use the slider to set things here @@ -729,7 +729,7 @@ static void rna_FModifier_end_frame_range( FModifier *fcm = (FModifier *)ptr->data; /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that, - * or else it becomes tricky to adjust the range, see: T36844. */ + * or else it becomes tricky to adjust the range, see: #36844. */ *min = MINAFRAMEF; *softmin = (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) ? fcm->sfra : MINAFRAMEF; @@ -951,7 +951,7 @@ static void rna_FModifierStepped_frame_start_set(PointerRNA *ptr, float value) value = CLAMPIS(value, prop_clamp_min, prop_clamp_max); /* Need to set both step-data's start/end and the start/end on the base-data, - * or else Restrict-Range doesn't work due to RNA-property shadowing (T52009) + * or else Restrict-Range doesn't work due to RNA-property shadowing (#52009) */ data->start_frame = value; fcm->sfra = value; @@ -968,7 +968,7 @@ static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value) value = CLAMPIS(value, prop_clamp_min, prop_clamp_max); /* Need to set both step-data's start/end and the start/end on the base-data, - * or else Restrict-Range doesn't work due to RNA-property shadowing (T52009) + * or else Restrict-Range doesn't work due to RNA-property shadowing (#52009) */ data->end_frame = value; fcm->efra = value; diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 97233f39d86..c8736b57863 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -203,7 +203,7 @@ static void rna_Image_alpha_mode_update(Main *bmain, Scene *scene, PointerRNA *p { Image *ima = (Image *)ptr->owner_id; /* When operating on a generated image, avoid re-generating when changing the alpha-mode - * as it doesn't impact generated images, causing them to reload pixel data, see T82785. */ + * as it doesn't impact generated images, causing them to reload pixel data, see #82785. */ if (ima->source == IMA_SRC_GENERATED) { return; } diff --git a/source/blender/makesrna/intern/rna_light.c b/source/blender/makesrna/intern/rna_light.c index f429fd73cdb..0ff0787de50 100644 --- a/source/blender/makesrna/intern/rna_light.c +++ b/source/blender/makesrna/intern/rna_light.c @@ -341,7 +341,7 @@ static void rna_def_light_shadow(StructRNA *srna, bool sun) RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text( prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows)"); - RNA_def_property_update(prop, 0, "rna_Light_update"); + RNA_def_property_update(prop, 0, "rna_Light_draw_update"); /* Eevee */ prop = RNA_def_property(srna, "use_contact_shadow", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 12b9c805701..f1de3185956 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -93,8 +93,7 @@ static void rna_Mesh_calc_smooth_groups( *r_poly_group_len = mesh->totpoly; const bool *sharp_edges = (const bool *)CustomData_get_layer_named( &mesh->edata, CD_PROP_BOOL, "sharp_edge"); - *r_poly_group = BKE_mesh_calc_smoothgroups(BKE_mesh_edges(mesh), - mesh->totedge, + *r_poly_group = BKE_mesh_calc_smoothgroups(mesh->totedge, BKE_mesh_polys(mesh), mesh->totpoly, BKE_mesh_loops(mesh), diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index b86e202a791..c8c1801876b 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3313,12 +3313,12 @@ static void rna_def_modifier_correctivesmooth(BlenderRNA *brna) "ORCO", 0, "Original Coords", - "Use base mesh vertex coords as the rest position"}, + "Use base mesh vertex coordinates as the rest position"}, {MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND, "BIND", 0, "Bind Coords", - "Use bind vertex coords for rest position"}, + "Use bind vertex coordinates for rest position"}, {0, NULL, 0, NULL, NULL}, }; @@ -5967,13 +5967,13 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna) "OVERWRITE", 0, "Overwrite", - "Replace vertex coords with cached values"}, + "Replace vertex coordinates with cached values"}, {MOD_MESHCACHE_DEFORM_INTEGRATE, "INTEGRATE", 0, "Integrate", - "Integrate deformation from this modifiers input with the mesh-cache coords (useful for " - "shape keys)"}, + "Integrate deformation from this modifier's input with the mesh-cache coordinates " + "(useful for shape keys)"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index ffd67b06037..4d284695ade 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -539,12 +539,12 @@ static NlaStrip *rna_NlaStrip_new(ID *id, strip->end += (start - strip->start); strip->start = start; - if (BKE_nlastrips_add_strip(&track->strips, strip)) { + if (!BKE_nlastrips_add_strip(&track->strips, strip)) { BKE_report( reports, RPT_ERROR, "Unable to add strip (the track does not have any space to accommodate this new strip)"); - BKE_nlastrip_free(NULL, strip, true); + BKE_nlastrip_free(strip, true); return NULL; } @@ -595,7 +595,7 @@ static void rna_NlaStrip_remove( return; } - BKE_nlastrip_free(&track->strips, strip, true); + BKE_nlastrip_remove_and_free(&track->strips, strip, true); RNA_POINTER_INVALIDATE(strip_ptr); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 7ba3971b4ea..71d6c72c05d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1435,6 +1435,11 @@ static void rna_NodeTree_active_output_set(PointerRNA *ptr, int value) } } +static bool rna_NodeTree_contains_tree(bNodeTree *tree, bNodeTree *sub_tree) +{ + return ntreeContainsTree(tree, sub_tree); +} + static bNodeSocket *rna_NodeTree_inputs_new( bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name) { @@ -9640,6 +9645,14 @@ static void def_geo_distribute_points_on_faces(StructRNA *srna) RNA_def_property_enum_default(prop, GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM); RNA_def_property_ui_text(prop, "Distribution Method", "Method to use for scattering points"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); + + prop = RNA_def_property(srna, "use_legacy_normal", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1); + RNA_def_property_ui_text(prop, + "Legacy Normal", + "Output the normal and rotation values that have been output " + "before the node started taking smooth normals into account"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); } static void def_geo_curve_spline_type(StructRNA *srna) @@ -10706,16 +10719,16 @@ static void def_geo_string_to_curves(StructRNA *srna) }; static const EnumPropertyItem rna_node_geometry_string_to_curves_align_y_items[] = { - {GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE, - "TOP_BASELINE", - ICON_ALIGN_TOP, - "Top Baseline", - "Align text to the top baseline"}, {GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP, "TOP", ICON_ALIGN_TOP, "Top", "Align text to the top"}, + {GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE, + "TOP_BASELINE", + ICON_ALIGN_TOP, + "Top Baseline", + "Align text to the top line's baseline"}, {GEO_NODE_STRING_TO_CURVES_ALIGN_Y_MIDDLE, "MIDDLE", ICON_ALIGN_MIDDLE, @@ -10725,7 +10738,7 @@ static void def_geo_string_to_curves(StructRNA *srna) "BOTTOM_BASELINE", ICON_ALIGN_BOTTOM, "Bottom Baseline", - "Align text to the bottom baseline"}, + "Align text to the bottom line's baseline"}, {GEO_NODE_STRING_TO_CURVES_ALIGN_Y_BOTTOM, "BOTTOM", ICON_ALIGN_BOTTOM, @@ -10777,21 +10790,24 @@ static void def_geo_string_to_curves(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "overflow"); RNA_def_property_enum_items(prop, rna_node_geometry_string_to_curves_overflow_items); RNA_def_property_enum_default(prop, GEO_NODE_STRING_TO_CURVES_MODE_OVERFLOW); - RNA_def_property_ui_text(prop, "Overflow", ""); + RNA_def_property_ui_text( + prop, "Textbox Overflow", "Handle the text behavior when it doesn't fit in the text boxes"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); prop = RNA_def_property(srna, "align_x", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "align_x"); RNA_def_property_enum_items(prop, rna_node_geometry_string_to_curves_align_x_items); RNA_def_property_enum_default(prop, GEO_NODE_STRING_TO_CURVES_ALIGN_X_LEFT); - RNA_def_property_ui_text(prop, "Align X", ""); + RNA_def_property_ui_text( + prop, "Horizontal Alignment", "Text horizontal alignment from the object center"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "align_y", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "align_y"); RNA_def_property_enum_items(prop, rna_node_geometry_string_to_curves_align_y_items); RNA_def_property_enum_default(prop, GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE); - RNA_def_property_ui_text(prop, "Align Y", ""); + RNA_def_property_ui_text( + prop, "Vertical Alignment", "Text vertical alignment from the object center"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "pivot_mode", PROP_ENUM, PROP_NONE); @@ -11203,6 +11219,14 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) prop, "Hide Value", "Hide the socket input value even when the socket is not connected"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + prop = RNA_def_property(srna, "hide_in_modifier", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_HIDE_IN_MODIFIER); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, + "Hide in Modifier", + "Don't show the input value in the geometry nodes modifier interface"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_domain_items); RNA_def_property_ui_text( @@ -12719,6 +12743,16 @@ static void rna_def_nodetree(BlenderRNA *brna) parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + func = RNA_def_function(srna, "contains_tree", "rna_NodeTree_contains_tree"); + RNA_def_function_ui_description( + func, + "Check if the node tree contains another. Used to avoid creating recursive node groups"); + parm = RNA_def_pointer( + func, "sub_tree", "NodeTree", "Node Tree", "Node tree for recursive check"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_property(func, "contained", PROP_BOOLEAN, PROP_NONE); + RNA_def_function_return(func, parm); + /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 71ad8dda859..56c66ddca3e 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -770,7 +770,7 @@ static void rna_Object_dup_collection_set(PointerRNA *ptr, Collection *grp = (Collection *)value.data; /* Must not let this be set if the object belongs in this group already, - * thus causing a cycle/infinite-recursion leading to crashes on load T25298. */ + * thus causing a cycle/infinite-recursion leading to crashes on load #25298. */ if (BKE_collection_has_object_recursive(grp, ob) == 0) { if (ob->type == OB_EMPTY) { id_us_min(&ob->instance_collection->id); @@ -2373,14 +2373,14 @@ static void rna_def_vertex_group(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Name", "Vertex group name"); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set"); - /* update data because modifiers may use T24761. */ + /* update data because modifiers may use #24761. */ RNA_def_property_update( prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data_dependency"); prop = RNA_def_property(srna, "lock_weight", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "", "Maintain the relative weights for the group"); RNA_def_property_boolean_sdna(prop, NULL, "flag", 0); - /* update data because modifiers may use T24761. */ + /* update data because modifiers may use #24761. */ RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data"); prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); @@ -2433,7 +2433,7 @@ static void rna_def_face_map(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Name", "Face map name"); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_FaceMap_name_set"); - /* update data because modifiers may use T24761. */ + /* update data because modifiers may use #24761. */ RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data"); prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index b4032ec8ab1..2064d5af82d 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -3141,7 +3141,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* children */ - /* NOTE(@campbellbarton): name is not following conventions: `nbr`. + /* NOTE(@ideasman42): name is not following conventions: `nbr`. * Could be changed next major version. */ prop = RNA_def_property(srna, "child_nbr", PROP_INT, PROP_NONE); RNA_def_property_int_sdna( diff --git a/source/blender/makesrna/intern/rna_path.cc b/source/blender/makesrna/intern/rna_path.cc index 420c8907107..a878acd5b77 100644 --- a/source/blender/makesrna/intern/rna_path.cc +++ b/source/blender/makesrna/intern/rna_path.cc @@ -832,7 +832,7 @@ static char *rna_idp_path(PointerRNA *ptr, * That case must be ignored here, we only want to deal with runtime RNA properties stored in * IDProps. * - * See T84091. */ + * See #84091. */ PropertyRNA *prop = RNA_struct_find_property(ptr, iter->name); if (prop == nullptr || (prop->flag & PROP_IDPROPERTY) == 0) { continue; @@ -906,7 +906,7 @@ static char *rna_path_from_ID_to_idpgroup(const PointerRNA *ptr) BLI_assert(ptr->owner_id != nullptr); /* TODO: Support Bones/PoseBones. no pointers stored to the bones from here, only the ID. - * See example in T25746. + * See example in #25746. * Unless this is added only way to find this is to also search * all bones and pose bones of an armature or object. */ @@ -1227,7 +1227,7 @@ char *RNA_path_full_struct_py(const PointerRNA *ptr) data_path = RNA_path_from_ID_to_struct(ptr); - /* XXX data_path may be NULL (see T36788), + /* XXX data_path may be NULL (see #36788), * do we want to get the 'bpy.data.foo["bar"].(null)' stuff? */ ret = BLI_sprintfN("%s.%s", id_path, data_path); diff --git a/source/blender/makesrna/intern/rna_pointcloud.c b/source/blender/makesrna/intern/rna_pointcloud.c index 49317857441..99ce90deaf4 100644 --- a/source/blender/makesrna/intern/rna_pointcloud.c +++ b/source/blender/makesrna/intern/rna_pointcloud.c @@ -162,7 +162,7 @@ static void rna_def_point(BlenderRNA *brna) prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_int_funcs(prop, "rna_Point_index_get", NULL, NULL); - RNA_def_property_ui_text(prop, "Index", "Index of this points"); + RNA_def_property_ui_text(prop, "Index", "Index of this point"); } static void rna_def_pointcloud(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 182f3ff6afa..1d37d83e2d9 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -600,7 +600,7 @@ static void rna_PoseChannel_constraints_remove( ED_object_constraint_update(bmain, ob); - /* XXX(@campbellbarton): is this really needed? */ + /* XXX(@ideasman42): is this really needed? */ BKE_constraints_active_set(&pchan->constraints, NULL); WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, id); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 6a66445ee4c..5eb00175c33 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -120,10 +120,7 @@ static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene { GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); GPU_shader_bind(shader); - - int img_loc = GPU_shader_get_uniform(shader, "image"); - - GPU_shader_uniform_int(shader, img_loc, 0); + /** \note "image" binding slot is 0. */ } static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine)) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5c75512183d..d8cb588319d 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1318,7 +1318,7 @@ static const EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext ID *id = ptr->owner_id; const bool is_render = (id && GS(id->name) == ID_SCE); - /* NOTE(@campbellbarton): we need to act differently for render + /* NOTE(@ideasman42): we need to act differently for render * where 'BW' will force grayscale even if the output format writes * as RGBA, this is age old blender convention and not sure how useful * it really is but keep it for now. */ @@ -6902,6 +6902,21 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop, "Simplify Volumes", "Resolution percentage of volume objects in viewport"); RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); + /* EEVEE - Simplify Options */ + prop = RNA_def_property(srna, "simplify_shadows_render", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 1.0); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text( + prop, "Simplify Shadows", "Resolution percentage of shadows in viewport"); + RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); + + prop = RNA_def_property(srna, "simplify_shadows", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 1.0); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text( + prop, "Simplify Shadows", "Resolution percentage of shadows in viewport"); + RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); + /* Grease Pencil - Simplify Options */ prop = RNA_def_property(srna, "simplify_gpencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_ENABLE); @@ -7257,6 +7272,17 @@ static void rna_def_scene_eevee(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem eevee_shadow_pool_size_items[] = { + {16, "16", 0, "16 MB", ""}, + {32, "32", 0, "32 MB", ""}, + {64, "64", 0, "64 MB", ""}, + {128, "128", 0, "128 MB", ""}, + {256, "256", 0, "256 MB", ""}, + {512, "512", 0, "512 MB", ""}, + {1024, "1024", 0, "1 GB", ""}, + {0, NULL, 0, NULL, NULL}, + }; + static const EnumPropertyItem eevee_gi_visibility_size_items[] = { {8, "8", 0, "8 px", ""}, {16, "16", 0, "16 px", ""}, @@ -7731,6 +7757,12 @@ static void rna_def_scene_eevee(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); /* Shadows */ + prop = RNA_def_property(srna, "use_shadows", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHADOW_ENABLED); + RNA_def_property_ui_text(prop, "Shadows", "Enable shadow casting from lights"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "shadow_cube_size", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, eevee_shadow_size_items); RNA_def_property_ui_text( @@ -7745,6 +7777,16 @@ static void rna_def_scene_eevee(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "shadow_pool_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, eevee_shadow_pool_size_items); + RNA_def_property_ui_text(prop, + "Shadow Pool Size", + "Size of the shadow pool, " + "bigger pool size allows for more shadows in the scene " + "but might not fits into GPU memory"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "use_shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHADOW_HIGH_BITDEPTH); RNA_def_property_ui_text(prop, "High Bit Depth", "Use 32-bit shadows"); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 3953fc66fc8..f586507427d 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -74,7 +74,7 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf * redrawing while the data is being modified for render */ if (!G.is_rendering) { /* can't use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call - * BKE_scene_graph_update_for_newframe which will lose any un-keyed changes T24690. */ + * BKE_scene_graph_update_for_newframe which will lose any un-keyed changes #24690. */ // WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); /* instead just redraw the views */ diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index a65bd613ecf..4d837a374d1 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -76,7 +76,7 @@ static void rna_Screen_redraw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), static bool rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr)) { - /* can be NULL on file load, T42619 */ + /* can be NULL on file load, #42619 */ wmWindowManager *wm = G_MAIN->wm.first; return wm ? (ED_screen_animation_playing(wm) != NULL) : 0; } @@ -103,7 +103,7 @@ static int rna_Area_type_get(PointerRNA *ptr) { ScrArea *area = (ScrArea *)ptr->data; /* Usually 'spacetype' is used. It lags behind a bit while switching area - * type though, then we use 'butspacetype' instead (T41435). */ + * type though, then we use 'butspacetype' instead (#41435). */ return (area->butspacetype == SPACE_EMPTY) ? area->spacetype : area->butspacetype; } @@ -130,7 +130,7 @@ static void rna_Area_type_update(bContext *C, PointerRNA *ptr) bScreen *screen = (bScreen *)ptr->owner_id; ScrArea *area = (ScrArea *)ptr->data; - /* Running update without having called 'set', see: T64049 */ + /* Running update without having called 'set', see: #64049 */ if (area->butspacetype == SPACE_EMPTY) { return; } @@ -377,7 +377,7 @@ static void rna_def_area(BlenderRNA *brna) * and needs to be read back by script authors. * * This happens when an area is full-screen (when #ScrArea.full is set). - * in this case reading the empty value is needed, but it should never be set, see: T87187. */ + * in this case reading the empty value is needed, but it should never be set, see: #87187. */ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "spacetype"); RNA_def_property_enum_items(prop, rna_enum_space_type_items); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 7c1cae1c44d..aa60339b7b8 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -228,7 +228,7 @@ static const EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, # else /* use this rather than PE_get_current() - because the editing cache is * dependent on the cache being updated which can happen after this UI - * draws causing a glitch T28883. */ + * draws causing a glitch #28883. */ ParticleSystem *psys = psys_get_current(ob); # endif diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 21843a5c223..55a71ceb14e 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -3128,7 +3128,7 @@ static void rna_def_gaussian_blur(StructRNA *srna) static void rna_def_text(StructRNA *srna) { - /* Avoid text icons because they imply this aligns within a frame, see: T71082 */ + /* Avoid text icons because they imply this aligns within a frame, see: #71082 */ static const EnumPropertyItem text_align_x_items[] = { {SEQ_TEXT_ALIGN_X_LEFT, "LEFT", ICON_ANCHOR_LEFT, "Left", ""}, {SEQ_TEXT_ALIGN_X_CENTER, "CENTER", ICON_ANCHOR_CENTER, "Center", ""}, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7bdbfe75684..ae07f2372b6 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2064,7 +2064,7 @@ static void rna_SpaceProperties_context_update(Main *UNUSED(bmain), PointerRNA *ptr) { SpaceProperties *sbuts = (SpaceProperties *)(ptr->data); - /* XXX BCONTEXT_DATA is ugly, but required for lights... See T51318. */ + /* XXX BCONTEXT_DATA is ugly, but required for lights... See #51318. */ if (ELEM(sbuts->mainb, BCONTEXT_WORLD, BCONTEXT_MATERIAL, BCONTEXT_TEXTURE, BCONTEXT_DATA)) { sbuts->preview = 1; } diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 9de32c24702..b768c7074b7 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -562,7 +562,7 @@ static void uilist_filter_items(uiList *ui_list, RNA_parameter_dynamic_length_get(&list, parm), "filter_flags", len); - /* NOTE: we cannot return here, we would let flt_data in inconsistent state... see T38356. */ + /* NOTE: we cannot return here, we would let flt_data in inconsistent state... see #38356. */ filter_flags = NULL; } else { @@ -578,7 +578,7 @@ static void uilist_filter_items(uiList *ui_list, RNA_parameter_dynamic_length_get(&list, parm), "filter_neworder", len); - /* NOTE: we cannot return here, we would let flt_data in inconsistent state... see T38356. */ + /* NOTE: we cannot return here, we would let flt_data in inconsistent state... see #38356. */ filter_neworder = NULL; } else { diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 12e86bb0129..1b10a924b12 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -373,7 +373,7 @@ static void rna_userdef_undo_steps_set(PointerRNA *ptr, int value) { UserDef *userdef = (UserDef *)ptr->data; - /* Do not allow 1 undo steps, useless and breaks undo/redo process (see T42531). */ + /* Do not allow 1 undo steps, useless and breaks undo/redo process (see #42531). */ userdef->undosteps = (value == 1) ? 2 : value; } @@ -605,7 +605,7 @@ static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRN static void rna_UserDef_viewport_lights_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - /* If all lights are off gpu_draw resets them all, see: T27627, + /* If all lights are off gpu_draw resets them all, see: #27627, * so disallow them all to be disabled. */ if (U.light_param[0].flag == 0 && U.light_param[1].flag == 0 && U.light_param[2].flag == 0 && U.light_param[3].flag == 0) { @@ -762,6 +762,13 @@ static const EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C } return items; } +# else +static int rna_lang_enum_properties_get_no_international(PointerRNA *UNUSED(ptr)) +{ + /* This simply prevents warnings when accessing language + * (since the actual value wont be in the enum, unless already `DEFAULT`). */ + return 0; +} # endif static IDProperty **rna_AddonPref_idprops(PointerRNA *ptr) @@ -2338,6 +2345,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera Path", ""); RNA_def_property_update(prop, 0, "rna_userdef_theme_update"); + prop = RNA_def_property(srna, "camera_passepartout", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Camera Passepartout", ""); + RNA_def_property_update(prop, 0, "rna_userdef_theme_update"); + prop = RNA_def_property(srna, "skin_root", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Skin Root", ""); @@ -4880,6 +4892,8 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_enum_items(prop, rna_enum_language_default_items); # ifdef WITH_INTERNATIONAL RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_lang_enum_properties_itemf"); +# else + RNA_def_property_enum_funcs(prop, "rna_lang_enum_properties_get_no_international", NULL, NULL); # endif RNA_def_property_ui_text(prop, "Language", "Language used for translation"); RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update"); @@ -6447,6 +6461,10 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) "All Linked Data Direct", "Forces all linked data to be considered as directly linked. Workaround for current " "issues/limitations in BAT (Blender studio pipeline tool)"); + + prop = RNA_def_property(srna, "use_new_volume_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text( + prop, "New Volume Nodes", "Enables visibility of the new Volume nodes in the UI"); } static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f712097bb54..e646258fb92 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1548,7 +1548,7 @@ static StructRNA *rna_Operator_register(Main *bmain, BLI_assert(ARRAY_SIZE(strings) == 5); } - /* XXX, this doubles up with the operator name T29666. + /* XXX, this doubles up with the operator name #29666. * for now just remove from dir(bpy.types) */ /* create a new operator type */ @@ -1702,7 +1702,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, BLI_assert(ARRAY_SIZE(strings) == 5); } - /* XXX, this doubles up with the operator name T29666. + /* XXX, this doubles up with the operator name #29666. * for now just remove from dir(bpy.types) */ /* create a new operator type */ @@ -2752,7 +2752,7 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed, -1 for any state"); RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); - /* XXX(@campbellbarton): the `*_ui` suffix is only for the UI, may be removed, + /* XXX(@ideasman42): the `*_ui` suffix is only for the UI, may be removed, * since this is only exposed so the UI can show these settings as toggle-buttons. */ prop = RNA_def_property(srna, "shift_ui", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shift", 0); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index b82458c4442..5d8bb533d7e 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -291,7 +291,7 @@ static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, kmi->flag |= KMI_REPEAT_IGNORE; } - /* T32437 allow scripts to define hotkeys that get added to start of keymap + /* #32437 allow scripts to define hotkeys that get added to start of keymap * so that they stand a chance against catch-all defines later on */ if (head) { diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c index a4630415ccd..23fd22b47b2 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo.c @@ -517,7 +517,7 @@ static void rna_Gizmo_unregister(struct Main *bmain, StructRNA *type) WM_gizmotype_remove_ptr(NULL, bmain, gzt); - /* Free extension after removing instances so `__del__` doesn't crash, see: T85567. */ + /* Free extension after removing instances so `__del__` doesn't crash, see: #85567. */ RNA_struct_free_extension(type, &gzt->rna_ext); RNA_struct_free(&BLENDER_RNA, type); @@ -916,7 +916,7 @@ static void rna_GizmoGroup_unregister(struct Main *bmain, StructRNA *type) WM_gizmo_group_type_remove_ptr(bmain, gzgt); - /* Free extension after removing instances so `__del__` doesn't crash, see: T85567. */ + /* Free extension after removing instances so `__del__` doesn't crash, see: #85567. */ RNA_struct_free_extension(type, &gzgt->rna_ext); RNA_struct_free(&BLENDER_RNA, type); diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 453c66c26a6..bc657717e38 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -237,7 +237,7 @@ static BMesh *BMD_mesh_bm_create( BMesh *bm = BM_mesh_create(&allocsize, &bmesh_create_params); /* Keep `mesh` first, needed so active layers are set based on `mesh` not `mesh_operand_ob`, - * otherwise the wrong active render layer is used, see T92384. + * otherwise the wrong active render layer is used, see #92384. * * NOTE: while initializing customer data layers the is not essential, * it avoids the overhead of having to re-allocate #BMHeader.data when the 2nd mesh is added diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index cb15ef965f9..334299ec767 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -499,7 +499,7 @@ static void deformVertsEM(ModifierData *md, BLI_assert(mesh->totvert == verts_num); } - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.cc b/source/blender/modifiers/intern/MOD_correctivesmooth.cc index bf98483ce8a..5a1d4dc637a 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.cc +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.cc @@ -764,7 +764,7 @@ static void deformVertsEM(ModifierData *md, Mesh *mesh_src = MOD_deform_mesh_eval_get( ctx->object, editData, mesh, nullptr, verts_num, false); - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_datatransfer.cc b/source/blender/modifiers/intern/MOD_datatransfer.cc index 7ac834c804a..80c78955d14 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.cc +++ b/source/blender/modifiers/intern/MOD_datatransfer.cc @@ -183,7 +183,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (((result == me) || (me_positions == result_positions) || (me_edges == result_edges)) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) { /* We need to duplicate data here, otherwise setting custom normals, edges' sharpness, etc., - * could modify org mesh, see T43671. */ + * could modify org mesh, see #43671. */ result = (Mesh *)BKE_id_copy_ex(nullptr, &me_mod->id, nullptr, LIB_ID_COPY_LOCALIZE); } diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index acbb64dfc55..1b3b10b3873 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -386,7 +386,7 @@ static void deformVertsEM(ModifierData *md, Mesh *mesh_src = MOD_deform_mesh_eval_get( ctx->object, editData, mesh, nullptr, verts_num, false); - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_explode.cc b/source/blender/modifiers/intern/MOD_explode.cc index 1bd399513b6..2fa50148332 100644 --- a/source/blender/modifiers/intern/MOD_explode.cc +++ b/source/blender/modifiers/intern/MOD_explode.cc @@ -752,7 +752,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) /* override original facepa (original pointer is saved in caller function) */ - /* TODO(@campbellbarton): `(totfsplit * 2)` over allocation is used since the quads are + /* TODO(@ideasman42): `(totfsplit * 2)` over allocation is used since the quads are * later interpreted as tri's, for this to work right I think we probably * have to stop using tessface. */ diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index aa8e7d541f0..c01ffd2e4fe 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -781,7 +781,7 @@ static void deformVertsEM(ModifierData *md, { Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.cc b/source/blender/modifiers/intern/MOD_laplaciansmooth.cc index 704235713e0..ae74de3e5a6 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.cc +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.cc @@ -553,7 +553,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false); - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 1269907971c..30801136eb4 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -588,7 +588,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, cut_edge.v1 = dst_loops[mp_dst.loopstart].v; cut_edge.v2 = cut_dst_loop.v; BLI_assert(cut_edge.v1 != cut_edge.v2); - cut_edge.flag = ME_EDGEDRAW; + cut_edge.flag = 0; edge_index++; /* Only handle one of the cuts per iteration. */ diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 3cbcf9845de..8cadc31b9c2 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -462,7 +462,7 @@ static void deformVertsEM(ModifierData *md, { Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc index c8628a7693e..16b54bd49bd 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc @@ -213,7 +213,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * XXX(Hans): This probably isn't true anymore with various CoW improvements, etc. */ if ((me_positions.data() == mesh_positions.data()) || (me_edges.data() == mesh_edges.data()) || (me_polys.data() == mesh_polys.data())) { - /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */ + /* We need to duplicate data here, otherwise we'll modify org mesh, see #51701. */ mesh = reinterpret_cast( BKE_id_copy_ex(nullptr, &mesh->id, diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 6ecd2c74462..15aab38bed7 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1736,7 +1736,9 @@ static void panel_draw(const bContext *C, Panel *panel) int socket_index; LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &nmd->node_group->inputs, socket_index) { - draw_property_for_socket(*C, layout, nmd, &bmain_ptr, ptr, *socket, socket_index); + if (!(socket->flag & SOCK_HIDE_IN_MODIFIER)) { + draw_property_for_socket(*C, layout, nmd, &bmain_ptr, ptr, *socket, socket_index); + } } } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index d6089372da6..aecbff5c7be 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -95,7 +95,7 @@ static void generate_vert_coordinates(Mesh *mesh, /* Translate our coordinates so that center of ob_center is at (0, 0, 0). */ /* Get ob_center (world) coordinates in ob local coordinates. - * No need to take into account ob_center's space here, see T44027. */ + * No need to take into account ob_center's space here, see #44027. */ invert_m4_m4(inv_obmat, ob->object_to_world); mul_v3_m4v3(diff, inv_obmat, ob_center->object_to_world[3]); negate_v3(diff); @@ -532,7 +532,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, if (BKE_mesh_edges(mesh) == BKE_mesh_edges((Mesh *)ob->data)) { /* We need to duplicate data here, otherwise setting custom normals * (which may also affect sharp edges) could - * modify original mesh, see T43671. */ + * modify original mesh, see #43671. */ result = (Mesh *)BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE); } else { diff --git a/source/blender/modifiers/intern/MOD_remesh.cc b/source/blender/modifiers/intern/MOD_remesh.cc index d35f4095acf..e57778841e2 100644 --- a/source/blender/modifiers/intern/MOD_remesh.cc +++ b/source/blender/modifiers/intern/MOD_remesh.cc @@ -178,7 +178,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, M } /* TODO(jbakker): Dualcon crashes when run in parallel. Could be related to incorrect * input data or that the library isn't thread safe. - * This was identified when changing the task isolation's during T76553. */ + * This was identified when changing the task isolation's during #76553. */ static ThreadMutex dualcon_mutex = BLI_MUTEX_INITIALIZER; BLI_mutex_lock(&dualcon_mutex); output = static_cast(dualcon(&input, diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 0b3514dcadd..0faf2da4f53 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -786,7 +786,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* add the new edge */ med_new->v1 = varray_stride + j; med_new->v2 = med_new->v1 - totvert; - med_new->flag = ME_EDGEDRAW; + med_new->flag = 0; med_new++; } } @@ -804,7 +804,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * for (i = 0; i < totvert; i++) { med_new->v1 = i; med_new->v2 = varray_stride + i; - med_new->flag = ME_EDGEDRAW; + med_new->flag = 0; med_new++; } } diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 8f63be85507..49944a14e28 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -130,7 +130,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); } - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 296cc2a4d44..27f5d5f2f32 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -168,7 +168,7 @@ static void simpleDeform_bend(const float factor, cost = cosf(theta); /* NOTE: the operations below a susceptible to float precision errors - * regarding the order of operations, take care when changing, see: T85470 */ + * regarding the order of operations, take care when changing, see: #85470 */ switch (axis) { case 0: r_co[0] = x; @@ -474,7 +474,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); } - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index e3fbd072f36..cdb7559a099 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -143,7 +143,7 @@ typedef struct Frame { struct Frame *frame; int corner; /* checked to avoid chaining. - * (merging when we're already been referenced), see T39775 */ + * (merging when we're already been referenced), see #39775 */ uint is_target : 1; } merge[4]; @@ -834,7 +834,7 @@ static int calc_edge_subdivisions(const float (*vert_positions)[3], const MEdge *e, const int *degree) { - /* prevent memory errors T38003. */ + /* prevent memory errors #38003. */ #define NUM_SUBDIVISIONS_MAX 128 const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]}; diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 8b0516bb13e..a2a42b176dd 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -210,7 +210,7 @@ static void deformVertsEM(ModifierData *md, /* mesh_src is needed for vgroups, and taking edges into account. */ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ BKE_mesh_wrapper_ensure_mdata(mesh_src); smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num); diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.cc b/source/blender/modifiers/intern/MOD_solidify_extrude.cc index 2c51c430e1e..9375a3eb59f 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.cc +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.cc @@ -32,7 +32,7 @@ /** \name High Quality Normal Calculation Function * \{ */ -/* skip shell thickness for non-manifold edges, see T35710. */ +/* skip shell thickness for non-manifold edges, see #35710. */ #define USE_NONMANIFOLD_WORKAROUND /* *** derived mesh high quality normal calculation function *** */ @@ -974,7 +974,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MEM_freeN(vert_nors); } - /* must recalculate normals with vgroups since they can displace unevenly T26888. */ + /* must recalculate normals with vgroups since they can displace unevenly #26888. */ if (BKE_mesh_vertex_normals_are_dirty(mesh) || do_rim || dvert) { BKE_mesh_normals_tag_dirty(result); } @@ -1012,7 +1012,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_rim) { uint i; - /* NOTE(@campbellbarton): Unfortunately re-calculate the normals for the new edge + /* NOTE(@ideasman42): Unfortunately re-calculate the normals for the new edge * faces is necessary. This could be done in many ways, but probably the quickest * way is to calculate the average normals for side faces only. * Then blend them with the normals of the edge verts. @@ -1054,7 +1054,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex for (i = 0; i < rimVerts; i++, ed++) { ed->v1 = new_vert_arr[i]; ed->v2 = (do_shell ? new_vert_arr[i] : i) + verts_num; - ed->flag |= ME_EDGEDRAW; if (orig_ed) { *orig_ed = ORIGINDEX_NONE; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc index 02d1119faaf..74a020d8a89 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc @@ -2073,7 +2073,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BLI_assert(v2 != MOD_SOLIDIFY_EMPTY_TAG); medge[insert].v1 = v1; medge[insert].v2 = v2; - medge[insert].flag = orig_medge[(*l)->old_edge].flag | ME_EDGEDRAW; + medge[insert].flag = orig_medge[(*l)->old_edge].flag; if (result_edge_crease) { result_edge_crease[insert] = orig_edge_crease ? orig_edge_crease[(*l)->old_edge] : 0.0f; @@ -2236,7 +2236,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } medge[edge_index].v1 = last_g->new_vert; medge[edge_index].v2 = g->new_vert; - medge[edge_index].flag = ME_EDGEDRAW | ((last_flag | flag) & ME_SEAM); + medge[edge_index].flag = ((last_flag | flag) & ME_SEAM); if (result_edge_crease) { result_edge_crease[edge_index] = max_ff(mv_crease, min_ff(last_max_crease, max_crease)); @@ -2269,7 +2269,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, last_g->open_face_edge = edge_index; medge[edge_index].v1 = last_g->new_vert; medge[edge_index].v2 = first_g->new_vert; - medge[edge_index].flag = ME_EDGEDRAW | ((last_flag | first_flag) & ME_SEAM); + medge[edge_index].flag = ((last_flag | first_flag) & ME_SEAM); if (result_edge_crease) { result_edge_crease[edge_index] = max_ff(mv_crease, min_ff(last_max_crease, first_max_crease)); diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 75377f00bb3..440c36fe19f 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -100,8 +100,11 @@ static void freeRuntimeData(void *runtime_data_v) return; } SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)runtime_data_v; - if (runtime_data->subdiv != nullptr) { - BKE_subdiv_free(runtime_data->subdiv); + if (runtime_data->subdiv_cpu != nullptr) { + BKE_subdiv_free(runtime_data->subdiv_cpu); + } + if (runtime_data->subdiv_gpu != nullptr) { + BKE_subdiv_free(runtime_data->subdiv_gpu); } MEM_freeN(runtime_data); } @@ -227,6 +230,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; + /* Decrement the recent usage counters. */ + if (runtime_data->used_cpu) { + runtime_data->used_cpu--; + } + + if (runtime_data->used_gpu) { + runtime_data->used_gpu--; + } + /* Delay evaluation to the draw code if possible, provided we do not have to apply the modifier. */ if ((ctx->flag & MOD_APPLY_TO_BASE_MESH) == 0) { @@ -273,7 +285,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); } // BKE_subdiv_stats_print(&subdiv->stats); - if (subdiv != runtime_data->subdiv) { + if (!ELEM(subdiv, runtime_data->subdiv_cpu, runtime_data->subdiv_gpu)) { BKE_subdiv_free(subdiv); } return result; @@ -305,7 +317,7 @@ static void deformMatrices(ModifierData *md, return; } BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num); - if (subdiv != runtime_data->subdiv) { + if (!ELEM(subdiv, runtime_data->subdiv_cpu, runtime_data->subdiv_gpu)) { BKE_subdiv_free(subdiv); } } @@ -409,12 +421,29 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(layout, ptr, "show_only_control_edges", 0, nullptr, ICON_NONE); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); SubsurfModifierData *smd = static_cast(ptr->data); - const Object *ob = static_cast(ob_ptr.data); + Object *ob = static_cast(ob_ptr.data); const Mesh *mesh = static_cast(ob->data); if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) { uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", ICON_INFO); } + else if (Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob)) { + if (ModifierData *md_eval = BKE_modifiers_findby_name(ob_eval, smd->modifier.name)) { + if (md_eval->type == eModifierType_Subsurf) { + SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)md_eval->runtime; + + if (runtime_data && runtime_data->used_gpu) { + if (runtime_data->used_cpu) { + uiItemL(layout, "Using both CPU and GPU subdivision", ICON_INFO); + } + else { + uiItemL(layout, "Using GPU subdivision", ICON_INFO); + } + } + } + } + } modifier_panel_end(layout, ptr); } diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.cc b/source/blender/modifiers/intern/MOD_surfacedeform.cc index 5ee9f4d5690..bbcbb80a771 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.cc +++ b/source/blender/modifiers/intern/MOD_surfacedeform.cc @@ -811,7 +811,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, const float edge_angle_a = bpoly->point_edgemid_angles[bpoly->dominant_edge]; const float edge_angle_b = bpoly->point_edgemid_angles[!bpoly->dominant_edge]; /* Clamp so skinny faces with near zero `edgemid_angle` - * won't cause numeric problems. see T81988. */ + * won't cause numeric problems. see #81988. */ scale_weight = edge_angle_a / max_ff(edge_angle_a, bpoly->edgemid_angle); scale_weight /= scale_weight + (edge_angle_b / max_ff(edge_angle_b, bpoly->edgemid_angle)); } @@ -888,7 +888,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, /* Apply after other kinds of scaling so the faces corner angle is always * scaled in a uniform way, preventing heavily sub-divided triangle fans - * from having a lop-sided influence on the weighting, see T81988. */ + * from having a lop-sided influence on the weighting, see #81988. */ bpoly->weight *= bpoly->edgemid_angle / M_PI; tot_weight += bpoly->weight; @@ -1592,7 +1592,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr, verts_num, false); } - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_triangulate.cc b/source/blender/modifiers/intern/MOD_triangulate.cc index adcf76a949d..66ffce98c65 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.cc +++ b/source/blender/modifiers/intern/MOD_triangulate.cc @@ -43,8 +43,6 @@ static Mesh *triangulate_mesh(Mesh *mesh, { Mesh *result; BMesh *bm; - int edges_num, i; - MEdge *me; CustomData_MeshMasks cd_mask_extra{}; cd_mask_extra.vmask = CD_MASK_ORIGINDEX; cd_mask_extra.emask = CD_MASK_ORIGINDEX; @@ -85,14 +83,6 @@ static Mesh *triangulate_mesh(Mesh *mesh, CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); } - edges_num = result->totedge; - me = BKE_mesh_edges_for_write(result); - - /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */ - for (i = 0; i < edges_num; i++, me++) { - me->flag |= ME_EDGEDRAW; - } - return result; } diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 2dfdd842a0c..b5fbac84257 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -371,7 +371,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, verts_num, false); } - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != NULL) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_wave.cc b/source/blender/modifiers/intern/MOD_wave.cc index 2eaaa78aee8..6cd6b83915d 100644 --- a/source/blender/modifiers/intern/MOD_wave.cc +++ b/source/blender/modifiers/intern/MOD_wave.cc @@ -329,7 +329,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false); } - /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ + /* TODO(@ideasman42): use edit-mode data only (remove this line). */ if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 6b8b917f3e0..cb97e88ac9f 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -314,6 +314,7 @@ DefNode(GeometryNode, GEO_NODE_DUAL_MESH, 0, "DUAL_MESH", DualMesh, "Dual Mesh", DefNode(GeometryNode, GEO_NODE_DUPLICATE_ELEMENTS, def_geo_duplicate_elements, "DUPLICATE_ELEMENTS", DuplicateElements, "Duplicate Elements", "Generate an arbitrary number copies of each selected input element") DefNode(GeometryNode, GEO_NODE_EDGE_PATHS_TO_CURVES, 0, "EDGE_PATHS_TO_CURVES", EdgePathsToCurves, "Edge Paths to Curves", "") DefNode(GeometryNode, GEO_NODE_EDGE_PATHS_TO_SELECTION, 0, "EDGE_PATHS_TO_SELECTION", EdgePathsToSelection, "Edge Paths to Selection", "") +DefNode(GeometryNode, GEO_NODE_EDGES_TO_FACE_GROUPS, 0, "EDGES_TO_FACE_GROUPS", EdgesToFaceGroups, "Edges to Face Groups", "Group faces into regions surrounded by the selected boundary edges") DefNode(GeometryNode, GEO_NODE_EVALUATE_AT_INDEX, def_geo_evaluate_at_index, "FIELD_AT_INDEX", FieldAtIndex, "Evaluate at Index", "Retrieve data of other elements in the context's geometry") DefNode(GeometryNode, GEO_NODE_EVALUATE_ON_DOMAIN, def_geo_evaluate_on_domain, "FIELD_ON_DOMAIN", FieldOnDomain, "Evaluate on Domain", "Retrieve values from a field on a different domain besides the domain from the context") DefNode(GeometryNode, GEO_NODE_EXTRUDE_MESH, def_geo_extrude_mesh, "EXTRUDE_MESH", ExtrudeMesh, "Extrude Mesh", "Generate new vertices, edges, or faces from selected elements and move them based on an offset while keeping them connected by their boundary") diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.cc b/source/blender/nodes/composite/nodes/node_composite_composite.cc index 70e4c2b5d3b..dafa87f93f0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_composite.cc +++ b/source/blender/nodes/composite/nodes/node_composite_composite.cc @@ -94,7 +94,7 @@ class CompositeOperation : public NodeOperation { image.bind_as_texture(shader, "input_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); const int2 compositing_region_size = context().get_compositing_region_size(); @@ -122,7 +122,7 @@ class CompositeOperation : public NodeOperation { image.bind_as_texture(shader, "input_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); const int2 compositing_region_size = context().get_compositing_region_size(); @@ -152,7 +152,7 @@ class CompositeOperation : public NodeOperation { alpha.bind_as_texture(shader, "alpha_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); const int2 compositing_region_size = context().get_compositing_region_size(); diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.cc b/source/blender/nodes/composite/nodes/node_composite_dilate.cc index 07063c1a06b..b34a7bd6646 100644 --- a/source/blender/nodes/composite/nodes/node_composite_dilate.cc +++ b/source/blender/nodes/composite/nodes/node_composite_dilate.cc @@ -122,7 +122,7 @@ class DilateErodeOperation : public NodeOperation { const int2 transposed_domain = int2(domain.size.y, domain.size.x); GPUTexture *horizontal_pass_result = texture_pool().acquire_color(transposed_domain); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(horizontal_pass_result, image_unit); compute_dispatch_threads_at_least(shader, domain.size); @@ -143,7 +143,7 @@ class DilateErodeOperation : public NodeOperation { GPU_shader_uniform_1i(shader, "radius", math::abs(get_distance())); GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH); - const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(horizontal_pass_result, texture_image_unit); const Domain domain = compute_domain(); @@ -273,7 +273,7 @@ class DilateErodeOperation : public NodeOperation { const int2 transposed_domain = int2(domain.size.y, domain.size.x); GPUTexture *horizontal_pass_result = texture_pool().acquire_color(transposed_domain); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(horizontal_pass_result, image_unit); compute_dispatch_threads_at_least(shader, domain.size); @@ -293,7 +293,7 @@ class DilateErodeOperation : public NodeOperation { GPU_shader_bind(shader); GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH); - const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int texture_image_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(horizontal_pass_result, texture_image_unit); const MorphologicalDistanceFeatherWeights &weights = diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index ad49d687220..27b864f9856 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -525,7 +525,7 @@ class ImageOperation : public NodeOperation { GPUShader *shader = shader_manager().get(get_shader_name(identifier)); GPU_shader_bind(shader); - const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(image_texture, input_unit); result.bind_as_image(shader, "output_img"); @@ -859,7 +859,7 @@ class RenderLayerOperation : public NodeOperation { const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); - const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(pass_texture, input_unit); const int2 compositing_region_size = context().get_compositing_region_size(); @@ -889,7 +889,7 @@ class RenderLayerOperation : public NodeOperation { const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); - const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(pass_texture, input_unit); const int2 compositing_region_size = context().get_compositing_region_size(); diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.cc b/source/blender/nodes/composite/nodes/node_composite_movieclip.cc index c55df061873..a3fa99d8356 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.cc +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.cc @@ -128,7 +128,7 @@ class MovieClipOperation : public NodeOperation { GPUShader *shader = shader_manager().get("compositor_convert_color_to_half_color"); GPU_shader_bind(shader); - const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(movie_clip_texture, input_unit); result.bind_as_image(shader, "output_img"); @@ -162,7 +162,7 @@ class MovieClipOperation : public NodeOperation { GPUShader *shader = shader_manager().get("compositor_extract_alpha_from_color"); GPU_shader_bind(shader); - const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(movie_clip_texture, input_unit); result.bind_as_image(shader, "output_img"); diff --git a/source/blender/nodes/composite/nodes/node_composite_output_file.cc b/source/blender/nodes/composite/nodes/node_composite_output_file.cc index 8939405cc07..51297794409 100644 --- a/source/blender/nodes/composite/nodes/node_composite_output_file.cc +++ b/source/blender/nodes/composite/nodes/node_composite_output_file.cc @@ -258,7 +258,7 @@ static void update_output_file(bNodeTree *ntree, bNode *node) { PointerRNA ptr; - /* XXX fix for T36706: remove invalid sockets added with bpy API. + /* XXX fix for #36706: remove invalid sockets added with bpy API. * This is not ideal, but prevents crashes from missing storage. * FileOutput node needs a redesign to support this properly. */ diff --git a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc index 73dcf42904c..c03a3a42dc9 100644 --- a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc +++ b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc @@ -77,7 +77,7 @@ class ViewerOperation : public NodeOperation { second_image.bind_as_texture(shader, "second_image_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); compute_dispatch_threads_at_least(shader, compositing_region_size); diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_viewer.cc index 66a16905d67..0beee8621ac 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.cc +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.cc @@ -123,7 +123,7 @@ class ViewerOperation : public NodeOperation { image.bind_as_texture(shader, "input_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); const int2 compositing_region_size = context().get_compositing_region_size(); @@ -151,7 +151,7 @@ class ViewerOperation : public NodeOperation { image.bind_as_texture(shader, "input_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); const int2 compositing_region_size = context().get_compositing_region_size(); @@ -181,7 +181,7 @@ class ViewerOperation : public NodeOperation { alpha.bind_as_texture(shader, "alpha_tx"); GPUTexture *output_texture = context().get_output_texture(); - const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); const int2 compositing_region_size = context().get_compositing_region_size(); diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc index df90c2103cc..416d0e754eb 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_value.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc @@ -170,7 +170,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) [](int min_value, int max_value, int id, int seed) -> int { const float value = noise::hash_to_float(id, seed); /* Add one to the maximum and use floor to produce an even - * distribution for the first and last values (See T93591). */ + * distribution for the first and last values (See #93591). */ return floor(value * (max_value + 1 - min_value) + min_value); }, mf::build::exec_presets::SomeSpanOrSingle<2>()); diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index 9fd3feff27e..448a5e69de4 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -69,6 +69,7 @@ set(SRC nodes/node_geo_edge_paths_to_curves.cc nodes/node_geo_edge_paths_to_selection.cc nodes/node_geo_edge_split.cc + nodes/node_geo_edges_to_face_groups.cc nodes/node_geo_evaluate_at_index.cc nodes/node_geo_evaluate_on_domain.cc nodes/node_geo_extrude_mesh.cc diff --git a/source/blender/nodes/geometry/node_geometry_register.cc b/source/blender/nodes/geometry/node_geometry_register.cc index 149fb6752ab..c6e0fc2697a 100644 --- a/source/blender/nodes/geometry/node_geometry_register.cc +++ b/source/blender/nodes/geometry/node_geometry_register.cc @@ -53,6 +53,7 @@ void register_geometry_nodes() register_node_type_geo_edge_paths_to_curves(); register_node_type_geo_edge_paths_to_selection(); register_node_type_geo_edge_split(); + register_node_type_geo_edges_to_face_groups(); register_node_type_geo_evaluate_at_index(); register_node_type_geo_evaluate_on_domain(); register_node_type_geo_extrude_mesh(); diff --git a/source/blender/nodes/geometry/node_geometry_register.hh b/source/blender/nodes/geometry/node_geometry_register.hh index 5984bfa83ce..900dd67cf71 100644 --- a/source/blender/nodes/geometry/node_geometry_register.hh +++ b/source/blender/nodes/geometry/node_geometry_register.hh @@ -50,6 +50,7 @@ void register_node_type_geo_duplicate_elements(); void register_node_type_geo_edge_paths_to_curves(); void register_node_type_geo_edge_paths_to_selection(); void register_node_type_geo_edge_split(); +void register_node_type_geo_edges_to_face_groups(); void register_node_type_geo_evaluate_at_index(); void register_node_type_geo_evaluate_on_domain(); void register_node_type_geo_extrude_mesh(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 9ec82d2666f..31d1bcb210c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -84,7 +84,6 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) MEdge &edge = edges[edge_index]; edge.v1 = v_from; edge.v2 = v_to; - edge.flag = ME_EDGEDRAW; /* Write edge index into both loops that have it. */ int reverse_index = plConvexHullGetReversedLoopIndex(hull, i); @@ -98,7 +97,6 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) MEdge &edge = edges[0]; edge.v1 = 0; edge.v2 = 1; - edge.flag = ME_EDGEDRAW; edge_index++; } BLI_assert(edge_index == edges_num); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index 7c433522300..ec30d832661 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_task.hh" + #include "BKE_curves.hh" #include "UI_interface.h" diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index 2f4ac6c878c..7657ded97ca 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -91,7 +91,6 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result &result) for (const int i : IndexRange(result.edge.size())) { edges[i].v1 = result.edge[i].first; edges[i].v2 = result.edge[i].second; - edges[i].flag = ME_EDGEDRAW; } int i_loop = 0; for (const int i : IndexRange(result.face.size())) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index 086a68401ed..b8138ef6769 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -219,7 +219,7 @@ class CurveStartPointInput final : public bke::CurvesFieldInput { return false; } - std::optional preferred_domain(const bke::CurvesGeometry & /*curves*/) + std::optional preferred_domain(const bke::CurvesGeometry & /*curves*/) const final { return ATTR_DOMAIN_CURVE; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index 912e846a3b9..5ed964c015e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -28,12 +28,14 @@ static void copy_data_based_on_map(const Span src, const Span index_map, MutableSpan dst) { - for (const int i_src : index_map.index_range()) { - const int i_dst = index_map[i_src]; - if (i_dst != -1) { - dst[i_dst] = src[i_src]; + threading::parallel_for(index_map.index_range(), 1024, [&](const IndexRange range) { + for (const int i_src : range) { + const int i_dst = index_map[i_src]; + if (i_dst != -1) { + dst[i_dst] = src[i_src]; + } } - } + }); } /** @@ -159,13 +161,15 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, const Span src_edges = src_mesh.edges(); MutableSpan dst_edges = dst_mesh.edges_for_write(); - for (const int i_src : IndexRange(src_mesh.totedge)) { - const int i_dst = edge_map[i_src]; - if (ELEM(i_dst, -1, -2)) { - continue; + threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange range) { + for (const int i_src : range) { + const int i_dst = edge_map[i_src]; + if (ELEM(i_dst, -1, -2)) { + continue; + } + dst_edges[i_dst] = src_edges[i_src]; } - dst_edges[i_dst] = src_edges[i_src]; - } + }); } static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, @@ -178,18 +182,20 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, const Span src_edges = src_mesh.edges(); MutableSpan dst_edges = dst_mesh.edges_for_write(); - for (const int i_src : IndexRange(src_mesh.totedge)) { - const int i_dst = edge_map[i_src]; - if (i_dst == -1) { - continue; - } - const MEdge &e_src = src_edges[i_src]; - MEdge &e_dst = dst_edges[i_dst]; + threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange range) { + for (const int i_src : range) { + const int i_dst = edge_map[i_src]; + if (i_dst == -1) { + continue; + } + const MEdge &e_src = src_edges[i_src]; + MEdge &e_dst = dst_edges[i_dst]; - e_dst = e_src; - e_dst.v1 = vertex_map[e_src.v1]; - e_dst.v2 = vertex_map[e_src.v2]; - } + e_dst = e_src; + e_dst.v1 = vertex_map[e_src.v1]; + e_dst.v2 = vertex_map[e_src.v2]; + } + }); } /* Faces and edges changed but vertices are the same. */ @@ -204,24 +210,26 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, MutableSpan dst_polys = dst_mesh.polys_for_write(); MutableSpan dst_loops = dst_mesh.loops_for_write(); - for (const int i_dst : masked_poly_indices.index_range()) { - const int i_src = masked_poly_indices[i_dst]; + threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) { + for (const int i_dst : range) { + const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_polys[i_src]; - MPoly &mp_dst = dst_polys[i_dst]; - const int i_ml_src = mp_src.loopstart; - const int i_ml_dst = new_loop_starts[i_dst]; + const MPoly &mp_src = src_polys[i_src]; + MPoly &mp_dst = dst_polys[i_dst]; + const int i_ml_src = mp_src.loopstart; + const int i_ml_dst = new_loop_starts[i_dst]; - const MLoop *ml_src = &src_loops[i_ml_src]; - MLoop *ml_dst = &dst_loops[i_ml_dst]; + const MLoop *ml_src = &src_loops[i_ml_src]; + MLoop *ml_dst = &dst_loops[i_ml_dst]; - mp_dst = mp_src; - mp_dst.loopstart = i_ml_dst; - for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = ml_src[i].v; - ml_dst[i].e = edge_map[ml_src[i].e]; + mp_dst = mp_src; + mp_dst.loopstart = i_ml_dst; + for (int i : IndexRange(mp_src.totloop)) { + ml_dst[i].v = ml_src[i].v; + ml_dst[i].e = edge_map[ml_src[i].e]; + } } - } + }); } /* Only faces changed. */ @@ -235,24 +243,26 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, MutableSpan dst_polys = dst_mesh.polys_for_write(); MutableSpan dst_loops = dst_mesh.loops_for_write(); - for (const int i_dst : masked_poly_indices.index_range()) { - const int i_src = masked_poly_indices[i_dst]; + threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) { + for (const int i_dst : range) { + const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_polys[i_src]; - MPoly &mp_dst = dst_polys[i_dst]; - const int i_ml_src = mp_src.loopstart; - const int i_ml_dst = new_loop_starts[i_dst]; + const MPoly &mp_src = src_polys[i_src]; + MPoly &mp_dst = dst_polys[i_dst]; + const int i_ml_src = mp_src.loopstart; + const int i_ml_dst = new_loop_starts[i_dst]; - const MLoop *ml_src = &src_loops[i_ml_src]; - MLoop *ml_dst = &dst_loops[i_ml_dst]; + const MLoop *ml_src = &src_loops[i_ml_src]; + MLoop *ml_dst = &dst_loops[i_ml_dst]; - mp_dst = mp_src; - mp_dst.loopstart = i_ml_dst; - for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = ml_src[i].v; - ml_dst[i].e = ml_src[i].e; + mp_dst = mp_src; + mp_dst.loopstart = i_ml_dst; + for (int i : IndexRange(mp_src.totloop)) { + ml_dst[i].v = ml_src[i].v; + ml_dst[i].e = ml_src[i].e; + } } - } + }); } static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, @@ -267,24 +277,26 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, MutableSpan dst_polys = dst_mesh.polys_for_write(); MutableSpan dst_loops = dst_mesh.loops_for_write(); - for (const int i_dst : masked_poly_indices.index_range()) { - const int i_src = masked_poly_indices[i_dst]; + threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) { + for (const int i_dst : range) { + const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_polys[i_src]; - MPoly &mp_dst = dst_polys[i_dst]; - const int i_ml_src = mp_src.loopstart; - const int i_ml_dst = new_loop_starts[i_dst]; + const MPoly &mp_src = src_polys[i_src]; + MPoly &mp_dst = dst_polys[i_dst]; + const int i_ml_src = mp_src.loopstart; + const int i_ml_dst = new_loop_starts[i_dst]; - const MLoop *ml_src = &src_loops[i_ml_src]; - MLoop *ml_dst = &dst_loops[i_ml_dst]; + const MLoop *ml_src = &src_loops[i_ml_src]; + MLoop *ml_dst = &dst_loops[i_ml_dst]; - mp_dst = mp_src; - mp_dst.loopstart = i_ml_dst; - for (int i : IndexRange(mp_src.totloop)) { - ml_dst[i].v = vertex_map[ml_src[i].v]; - ml_dst[i].e = edge_map[ml_src[i].e]; + mp_dst = mp_src; + mp_dst.loopstart = i_ml_dst; + for (int i : IndexRange(mp_src.totloop)) { + ml_dst[i].v = vertex_map[ml_src[i].v]; + ml_dst[i].e = edge_map[ml_src[i].e]; + } } - } + }); } static void delete_curves_selection(GeometrySet &geometry_set, @@ -574,16 +586,20 @@ static void compute_selected_mesh_data_from_vertex_selection_edge_face( int *r_selected_polys_num, int *r_selected_loops_num) { - - compute_selected_edges_from_vertex_selection( - mesh, vertex_selection, r_edge_map, r_selected_edges_num); - - compute_selected_polys_from_vertex_selection(mesh, - vertex_selection, - r_selected_poly_indices, - r_loop_starts, - r_selected_polys_num, - r_selected_loops_num); + threading::parallel_invoke( + mesh.totedge > 1000, + [&]() { + compute_selected_edges_from_vertex_selection( + mesh, vertex_selection, r_edge_map, r_selected_edges_num); + }, + [&]() { + compute_selected_polys_from_vertex_selection(mesh, + vertex_selection, + r_selected_poly_indices, + r_loop_starts, + r_selected_polys_num, + r_selected_loops_num); + }); } /** @@ -601,18 +617,24 @@ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh, int *r_selected_polys_num, int *r_selected_loops_num) { - compute_selected_verts_from_vertex_selection( - vertex_selection, r_vertex_map, r_selected_verts_num); - - compute_selected_edges_from_vertex_selection( - mesh, vertex_selection, r_edge_map, r_selected_edges_num); - - compute_selected_polys_from_vertex_selection(mesh, - vertex_selection, - r_selected_poly_indices, - r_loop_starts, - r_selected_polys_num, - r_selected_loops_num); + threading::parallel_invoke( + mesh.totedge > 1000, + [&]() { + compute_selected_verts_from_vertex_selection( + vertex_selection, r_vertex_map, r_selected_verts_num); + }, + [&]() { + compute_selected_edges_from_vertex_selection( + mesh, vertex_selection, r_edge_map, r_selected_edges_num); + }, + [&]() { + compute_selected_polys_from_vertex_selection(mesh, + vertex_selection, + r_selected_poly_indices, + r_loop_starts, + r_selected_polys_num, + r_selected_loops_num); + }); } /** @@ -629,14 +651,20 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face( int *r_selected_polys_num, int *r_selected_loops_num) { - compute_selected_edges_from_edge_selection( - mesh, edge_selection, r_edge_map, r_selected_edges_num); - compute_selected_polys_from_edge_selection(mesh, - edge_selection, - r_selected_poly_indices, - r_loop_starts, - r_selected_polys_num, - r_selected_loops_num); + threading::parallel_invoke( + mesh.totedge > 1000, + [&]() { + compute_selected_edges_from_edge_selection( + mesh, edge_selection, r_edge_map, r_selected_edges_num); + }, + [&]() { + compute_selected_polys_from_edge_selection(mesh, + edge_selection, + r_selected_poly_indices, + r_loop_starts, + r_selected_polys_num, + r_selected_loops_num); + }); } /** @@ -654,15 +682,25 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, int *r_selected_polys_num, int *r_selected_loops_num) { - r_vertex_map.fill(-1); - compute_selected_verts_and_edges_from_edge_selection( - mesh, edge_selection, r_vertex_map, r_edge_map, r_selected_verts_num, r_selected_edges_num); - compute_selected_polys_from_edge_selection(mesh, - edge_selection, - r_selected_poly_indices, - r_loop_starts, - r_selected_polys_num, - r_selected_loops_num); + threading::parallel_invoke( + mesh.totedge > 1000, + [&]() { + r_vertex_map.fill(-1); + compute_selected_verts_and_edges_from_edge_selection(mesh, + edge_selection, + r_vertex_map, + r_edge_map, + r_selected_verts_num, + r_selected_edges_num); + }, + [&]() { + compute_selected_polys_from_edge_selection(mesh, + edge_selection, + r_selected_poly_indices, + r_loop_starts, + r_selected_polys_num, + r_selected_loops_num); + }); } /** diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index d37f36e17a5..0e459566d47 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -67,6 +67,11 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE); } +static void node_layout_ex(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) +{ + uiItemR(layout, ptr, "use_legacy_normal", 0, nullptr, ICON_NONE); +} + static void node_point_distribute_points_on_faces_update(bNodeTree *ntree, bNode *node) { bNodeSocket *sock_distance_min = static_cast(BLI_findlink(&node->inputs, 2)); @@ -325,11 +330,73 @@ struct AttributeOutputs { }; } // namespace +static void compute_normal_outputs(const Mesh &mesh, + const Span bary_coords, + const Span looptri_indices, + MutableSpan r_normals) +{ + Array corner_normals(mesh.totloop); + BKE_mesh_calc_normals_split_ex( + const_cast(&mesh), nullptr, reinterpret_cast(corner_normals.data())); + + const Span looptris = mesh.looptris(); + + threading::parallel_for(bary_coords.index_range(), 512, [&](const IndexRange range) { + for (const int i : range) { + const int looptri_index = looptri_indices[i]; + const MLoopTri &looptri = looptris[looptri_index]; + const float3 &bary_coord = bary_coords[i]; + + const float3 normal = math::normalize( + bke::mesh_surface_sample::sample_corner_attrribute_with_bary_coords( + bary_coord, looptri, corner_normals.as_span())); + + r_normals[i] = normal; + } + }); +} + +static void compute_legacy_normal_outputs(const Mesh &mesh, + const Span bary_coords, + const Span looptri_indices, + MutableSpan r_normals) +{ + const Span positions = mesh.vert_positions(); + const Span loops = mesh.loops(); + const Span looptris = mesh.looptris(); + + for (const int i : bary_coords.index_range()) { + const int looptri_index = looptri_indices[i]; + const MLoopTri &looptri = looptris[looptri_index]; + + const int v0_index = loops[looptri.tri[0]].v; + const int v1_index = loops[looptri.tri[1]].v; + const int v2_index = loops[looptri.tri[2]].v; + const float3 v0_pos = positions[v0_index]; + const float3 v1_pos = positions[v1_index]; + const float3 v2_pos = positions[v2_index]; + + float3 normal; + normal_tri_v3(normal, v0_pos, v1_pos, v2_pos); + r_normals[i] = normal; + } +} + +static void compute_rotation_output(const Span normals, MutableSpan r_rotations) +{ + threading::parallel_for(normals.index_range(), 256, [&](const IndexRange range) { + for (const int i : range) { + r_rotations[i] = normal_to_euler_rotation(normals[i]); + } + }); +} + BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, PointCloud &points, const Span bary_coords, const Span looptri_indices, - const AttributeOutputs &attribute_outputs) + const AttributeOutputs &attribute_outputs, + const bool use_legacy_normal) { MutableAttributeAccessor point_attributes = points.attributes_for_write(); @@ -348,33 +415,24 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, attribute_outputs.rotation_id.get(), ATTR_DOMAIN_POINT); } - const Span positions = mesh.vert_positions(); - const Span loops = mesh.loops(); - const Span looptris = mesh.looptris(); - - for (const int i : bary_coords.index_range()) { - const int looptri_index = looptri_indices[i]; - const MLoopTri &looptri = looptris[looptri_index]; - const float3 &bary_coord = bary_coords[i]; - - const int v0_index = loops[looptri.tri[0]].v; - const int v1_index = loops[looptri.tri[1]].v; - const int v2_index = loops[looptri.tri[2]].v; - const float3 v0_pos = positions[v0_index]; - const float3 v1_pos = positions[v1_index]; - const float3 v2_pos = positions[v2_index]; - - ids.span[i] = noise::hash(noise::hash_float(bary_coord), looptri_index); - - float3 normal; - if (!normals.span.is_empty() || !rotations.span.is_empty()) { - normal_tri_v3(normal, v0_pos, v1_pos, v2_pos); + threading::parallel_for(bary_coords.index_range(), 1024, [&](const IndexRange range) { + for (const int i : range) { + const int looptri_index = looptri_indices[i]; + const float3 &bary_coord = bary_coords[i]; + ids.span[i] = noise::hash(noise::hash_float(bary_coord), looptri_index); } - if (!normals.span.is_empty()) { - normals.span[i] = normal; + }); + + if (normals) { + if (use_legacy_normal) { + compute_legacy_normal_outputs(mesh, bary_coords, looptri_indices, normals.span); } - if (!rotations.span.is_empty()) { - rotations.span[i] = normal_to_euler_rotation(normal); + else { + compute_normal_outputs(mesh, bary_coords, looptri_indices, normals.span); + } + + if (rotations) { + compute_rotation_output(normals.span, rotations.span); } } @@ -507,7 +565,9 @@ static void point_distribution_calculate(GeometrySet &geometry_set, propagate_existing_attributes(mesh, attributes, *pointcloud, bary_coords, looptri_indices); - compute_attribute_outputs(mesh, *pointcloud, bary_coords, looptri_indices, attribute_outputs); + const bool use_legacy_normal = params.node().custom2 != 0; + compute_attribute_outputs( + mesh, *pointcloud, bary_coords, looptri_indices, attribute_outputs, use_legacy_normal); } static void node_geo_exec(GeoNodeExecParams params) @@ -521,8 +581,9 @@ static void node_geo_exec(GeoNodeExecParams params) const Field selection_field = params.extract_input>("Selection"); AttributeOutputs attribute_outputs; - attribute_outputs.normal_id = params.get_output_anonymous_attribute_id_if_needed("Normal"); attribute_outputs.rotation_id = params.get_output_anonymous_attribute_id_if_needed("Rotation"); + attribute_outputs.normal_id = params.get_output_anonymous_attribute_id_if_needed( + "Normal", bool(attribute_outputs.rotation_id)); lazy_threading::send_hint(); @@ -567,5 +628,6 @@ void register_node_type_geo_distribute_points_on_faces() ntype.declare = file_ns::node_declare; ntype.geometry_node_execute = file_ns::node_geo_exec; ntype.draw_buttons = file_ns::node_layout; + ntype.draw_buttons_ex = file_ns::node_layout_ex; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index 8e51e8ac2b5..c4f88b8ac75 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -540,7 +540,7 @@ static bool vertex_needs_dissolving(const int vertex, * used in the data-structures derived from the mesh. For each pair of polygons which has such a * vertex, an edge is created for the dual mesh between the centers of those two polygons. All * edges in the input mesh which contain such a vertex are marked as 'done' to prevent duplicate - * edges being created. (See T94144) + * edges being created. (See #94144) */ static void dissolve_redundant_verts(const Span edges, const Span polys, diff --git a/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc b/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc new file mode 100644 index 00000000000..b89ad0dfd14 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_edges_to_face_groups.cc @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" + +#include "BLI_atomic_disjoint_set.hh" + +#include "node_geometry_util.hh" + +namespace blender::nodes::node_geo_edges_to_face_groups_cc { + +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_input("Boundary Edges") + .default_value(true) + .hide_value() + .supports_field() + .description(N_("Edges used to split faces into separate groups")); + b.add_output("Face Group ID") + .dependent_field() + .description(N_("Index of the face group inside each boundary edge region")); +} + +/** Join all unique unordered combinations of indices. */ +static void join_indices(AtomicDisjointSet &set, const Span indices) +{ + for (const int i : indices.index_range()) { + for (int j = i + 1; j < indices.size(); j++) { + set.join(indices[i], indices[j]); + } + } +} + +class FaceSetFromBoundariesInput final : public bke::MeshFieldInput { + private: + Field non_boundary_edge_field_; + + public: + FaceSetFromBoundariesInput(Field selection) + : bke::MeshFieldInput(CPPType::get(), "Edges to Face Groups"), + non_boundary_edge_field_(std::move(selection)) + { + } + + GVArray get_varray_for_context(const Mesh &mesh, + const eAttrDomain domain, + const IndexMask /*mask*/) const final + { + const bke::MeshFieldContext context{mesh, ATTR_DOMAIN_EDGE}; + fn::FieldEvaluator evaluator{context, mesh.totedge}; + evaluator.add(non_boundary_edge_field_); + evaluator.evaluate(); + const IndexMask non_boundary_edges = evaluator.get_evaluated_as_mask(0); + + const Span polys = mesh.polys(); + const Span loops = mesh.loops(); + + const Array> edge_to_face_map = bke::mesh_topology::build_edge_to_poly_map( + polys, loops, mesh.totedge); + + AtomicDisjointSet islands(polys.size()); + for (const int edge : non_boundary_edges) { + join_indices(islands, edge_to_face_map[edge]); + } + + Array output(polys.size()); + islands.calc_reduced_ids(output); + + return mesh.attributes().adapt_domain( + VArray::ForContainer(std::move(output)), ATTR_DOMAIN_FACE, domain); + } + + uint64_t hash() const override + { + return non_boundary_edge_field_.hash(); + } + + bool is_equal_to(const fn::FieldNode &other) const override + { + if (const auto *other_field = dynamic_cast(&other)) { + return other_field->non_boundary_edge_field_ == non_boundary_edge_field_; + } + return false; + } + + std::optional preferred_domain(const Mesh & /*mesh*/) const final + { + return ATTR_DOMAIN_FACE; + } +}; + +static void geo_node_exec(GeoNodeExecParams params) +{ + Field boundary_edges = params.extract_input>("Boundary Edges"); + Field non_boundary_edges = fn::invert_boolean_field(std::move(boundary_edges)); + params.set_output( + "Face Group ID", + Field(std::make_shared(std::move(non_boundary_edges)))); +} + +} // namespace blender::nodes::node_geo_edges_to_face_groups_cc + +void register_node_type_geo_edges_to_face_groups() +{ + namespace file_ns = blender::nodes::node_geo_edges_to_face_groups_cc; + + static bNodeType ntype; + + geo_node_type_base( + &ntype, GEO_NODE_EDGES_TO_FACE_GROUPS, "Edges to Face Groups", NODE_CLASS_INPUT); + ntype.geometry_node_execute = file_ns::geo_node_exec; + ntype.declare = file_ns::node_declare; + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 28691252729..63d84076654 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -10,6 +10,7 @@ #include "BKE_attribute_math.hh" #include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" #include "BKE_mesh_runtime.h" #include "UI_interface.h" @@ -151,7 +152,7 @@ static MEdge new_edge(const int v1, const int v2) MEdge edge; edge.v1 = v1; edge.v2 = v2; - edge.flag = ME_EDGEDRAW; + edge.flag = 0; return edge; } @@ -288,22 +289,6 @@ static void extrude_mesh_vertices(Mesh &mesh, BKE_mesh_runtime_clear_cache(&mesh); } -static Array> mesh_calculate_polys_of_edge(const Mesh &mesh) -{ - const Span polys = mesh.polys(); - const Span loops = mesh.loops(); - Array> polys_of_edge(mesh.totedge); - - for (const int i_poly : polys.index_range()) { - const MPoly &poly = polys[i_poly]; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - polys_of_edge[loop.e].append(i_poly); - } - } - - return polys_of_edge; -} - static void fill_quad_consistent_direction(Span other_poly_loops, MutableSpan new_loops, const int vert_connected_to_poly_1, @@ -382,7 +367,8 @@ static void extrude_mesh_edges(Mesh &mesh, return; } - const Array> edge_to_poly_map = mesh_calculate_polys_of_edge(mesh); + const Array> edge_to_poly_map = bke::mesh_topology::build_edge_to_poly_map( + orig_polys, mesh.loops(), mesh.totedge); /* Find the offsets on the vertex domain for translation. This must be done before the mesh's * custom data layers are reallocated, in case the virtual array references one of them. */ @@ -684,7 +670,8 @@ static void extrude_mesh_face_regions(Mesh &mesh, } /* All of the faces (selected and deselected) connected to each edge. */ - const Array> edge_to_poly_map = mesh_calculate_polys_of_edge(mesh); + const Array> edge_to_poly_map = bke::mesh_topology::build_edge_to_poly_map( + orig_polys, orig_loops, orig_edges.size()); /* All vertices that are connected to the selected polygons. * Start the size at one vert per poly to reduce unnecessary reallocation. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index 4b4d7ecb702..7d465b9147e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -129,7 +129,6 @@ static Mesh *create_circle_mesh(const float radius, MEdge &edge = edges[i]; edge.v1 = i; edge.v2 = (i + 1) % verts_num; - edge.flag = ME_EDGEDRAW; } /* Create triangle fan edges. */ @@ -138,7 +137,6 @@ static Mesh *create_circle_mesh(const float radius, MEdge &edge = edges[verts_num + i]; edge.v1 = verts_num; edge.v2 = i; - edge.flag = ME_EDGEDRAW; } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 757fab12e82..173aa22b77d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -329,7 +329,6 @@ static void calculate_cone_edges(const ConeConfig &config, MutableSpan ed MEdge &edge = edges[edge_index++]; edge.v1 = config.first_vert; edge.v2 = config.first_ring_verts_start + i; - edge.flag = ME_EDGEDRAW; } } @@ -342,7 +341,6 @@ static void calculate_cone_edges(const ConeConfig &config, MutableSpan ed MEdge &edge = edges[edge_index++]; edge.v1 = this_ring_vert_start + j; edge.v2 = this_ring_vert_start + ((j + 1) % config.circle_segments); - edge.flag = ME_EDGEDRAW; } if (i == config.tot_edge_rings - 1) { /* There is one fewer ring of connecting edges. */ @@ -353,7 +351,6 @@ static void calculate_cone_edges(const ConeConfig &config, MutableSpan ed MEdge &edge = edges[edge_index++]; edge.v1 = this_ring_vert_start + j; edge.v2 = next_ring_vert_start + j; - edge.flag = ME_EDGEDRAW; } } @@ -363,7 +360,6 @@ static void calculate_cone_edges(const ConeConfig &config, MutableSpan ed MEdge &edge = edges[edge_index++]; edge.v1 = config.last_ring_verts_start + i; edge.v2 = config.last_vert; - edge.flag = ME_EDGEDRAW; } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index 4e6cc590a7b..16821925e2a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -93,7 +93,6 @@ Mesh *create_grid_mesh(const int verts_x, MEdge &edge = edges[y_edge_offset + y]; edge.v1 = vert_index; edge.v2 = vert_index + 1; - edge.flag = ME_EDGEDRAW; } }); } @@ -109,7 +108,6 @@ Mesh *create_grid_mesh(const int verts_x, MEdge &edge = edges[x_edge_offset + x]; edge.v1 = vert_index; edge.v2 = vert_index + verts_y; - edge.flag = ME_EDGEDRAW; } }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index a93fccb3f37..9d65d961f04 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -117,7 +117,6 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan edges, MEdge &edge = edges[edge_index++]; edge.v1 = 0; edge.v2 = first_vert_ring_index_start + segment; - edge.flag = ME_EDGEDRAW; } int ring_vert_index_start = 1; @@ -129,7 +128,6 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan edges, MEdge &edge = edges[edge_index++]; edge.v1 = ring_vert_index_start + segment; edge.v2 = ring_vert_index_start + ((segment + 1) % segments); - edge.flag = ME_EDGEDRAW; } /* Add the edges connecting to the next ring. */ @@ -138,7 +136,6 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan edges, MEdge &edge = edges[edge_index++]; edge.v1 = ring_vert_index_start + segment; edge.v2 = next_ring_vert_index_start + segment; - edge.flag = ME_EDGEDRAW; } } ring_vert_index_start += segments; @@ -151,7 +148,6 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan edges, MEdge &edge = edges[edge_index++]; edge.v1 = last_vert_index; edge.v2 = last_vert_ring_start + segment; - edge.flag = ME_EDGEDRAW; } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc index dbf75f1c0b5..c2a9f92cf8c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc @@ -2,6 +2,8 @@ #include +#include "BLI_task.hh" + #include "BKE_curves.hh" #include "UI_interface.h" diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc index 4f7bf3714f2..a3c9999facd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc @@ -6,6 +6,7 @@ #include "BLI_math_matrix.hh" #include "BLI_math_matrix_types.hh" +#include "BLI_task.hh" #include "DNA_mesh_types.h" #include "DNA_pointcloud_types.h" diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 6c05234f1e8..b17c41f8189 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -114,7 +114,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, ParamKey vkeys[2]{edge.v1, edge.v2}; GEO_uv_parametrizer_edge_set_seam(handle, vkeys); } - /* TODO: once field input nodes are able to emit warnings (T94039), emit a + /* TODO: once field input nodes are able to emit warnings (#94039), emit a * warning if we fail to solve an island. */ GEO_uv_parametrizer_construct_end(handle, fill_holes, false, nullptr); diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc index 691ffc936a7..cae24ef4b0a 100644 --- a/source/blender/nodes/shader/node_shader_tree.cc +++ b/source/blender/nodes/shader/node_shader_tree.cc @@ -367,7 +367,7 @@ static void ntree_shader_groups_expand_inputs(bNodeTree *localtree) LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { if (socket->link != nullptr && !(socket->link->flag & NODE_LINK_MUTED)) { bNodeLink *link = socket->link; - /* Fix the case where the socket is actually converting the data. (see T71374) + /* Fix the case where the socket is actually converting the data. (see #71374) * We only do the case of lossy conversion to float. */ if ((socket->type == SOCK_FLOAT) && (link->fromsock->type != link->tosock->type)) { if (link->fromsock->type == SOCK_RGBA) { @@ -439,7 +439,7 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode) LISTBASE_FOREACH_MUTABLE (bNode *, node, &ngroup->nodes) { /* Remove interface nodes. * This also removes remaining links to and from interface nodes. - * We must delay removal since sockets will reference this node. see: T52092 */ + * We must delay removal since sockets will reference this node. see: #52092 */ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { BLI_linklist_prepend(&group_interface_nodes, node); } @@ -448,7 +448,7 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode) BLI_addtail(&ntree->nodes, node); nodeUniqueID(ntree, node); /* ensure unique node name in the node tree */ - /* This is very slow and it has no use for GPU nodetree. (see T70609) */ + /* This is very slow and it has no use for GPU nodetree. (see #70609) */ // nodeUniqueName(ntree, node); } ngroup->runtime->nodes_by_id.clear(); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index cf160c2c277..fe3f2e2c8d0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -173,7 +173,7 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, flag |= GPU_MATFLAG_CLEARCOAT; } - /* Ref. T98190: Defines are optimizations for old compilers. + /* Ref. #98190: Defines are optimizations for old compilers. * Might become unnecessary with EEVEE-Next. */ if (use_diffuse == false && use_refract == false && use_clear == true) { flag |= GPU_MATFLAG_PRINCIPLED_CLEARCOAT; diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.cc b/source/blender/nodes/shader/nodes/node_shader_bump.cc index 9439f95d62b..86c5aa99013 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bump.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bump.cc @@ -59,6 +59,14 @@ static int gpu_shader_bump(GPUMaterial *mat, const char *height_function = GPU_material_split_sub_function(mat, GPU_FLOAT, &in[2].link); + /* TODO (Miguel Pozo): + * Currently, this doesn't compute the actual differentials, just the height at dX and dY + * offsets. The actual differentials are computed inside the GLSL node_bump function by + * subtracting the height input. This avoids redundant computations when the height input is + * also needed by regular nodes as part in the main function (See #103903 for context). + * A better option would be to add a "value" input socket (in this case the height) to the + * differentiate node, but currently this kind of intermediate nodes are pruned in the + * code generation process (see #104265), so we need to fix that first. */ GPUNodeLink *dheight = GPU_differentiate_float_function(height_function); float invert = (node->custom1) ? -1.0 : 1.0; diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.cc b/source/blender/nodes/shader/nodes/node_shader_geometry.cc index d7d5f4aa91f..5ef2fec474b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geometry.cc +++ b/source/blender/nodes/shader/nodes/node_shader_geometry.cc @@ -41,7 +41,7 @@ static int node_shader_gpu_geometry(GPUMaterial *mat, /* Normalize some vectors after dFdx/dFdy offsets. * This is the case for interpolated, non linear functions. * The resulting vector can still be a bit wrong but not as much. - * (see T70644) */ + * (see #70644) */ if (ELEM(i, 1, 2, 4)) { GPU_link(mat, "vector_math_normalize", diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc index a295bda9d07..bd0e195821b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc @@ -54,7 +54,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, /* Normalize some vectors after dFdx/dFdy offsets. * This is the case for interpolated, non linear functions. * The resulting vector can still be a bit wrong but not as much. - * (see T70644) */ + * (see #70644) */ if (ELEM(i, 1, 6)) { GPU_link(mat, "vector_math_normalize", diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc index de8221e3e97..d054457220c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc +++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc @@ -53,7 +53,7 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat, /* NOTE: using CD_AUTO_FROM_NAME instead of CD_MTFACE as geometry nodes may overwrite data which * will also change the eCustomDataType. This will also make EEVEE and Cycles consistent. See - * T93179. */ + * #93179. */ GPUNodeLink *mtface = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->uv_map); GPU_stack_link(mat, node, "node_uvmap", in, out, mtface); diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc index 0e0f9496851..da75f915507 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc @@ -49,7 +49,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat, NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage; /* NOTE: Using #CD_AUTO_FROM_NAME is necessary because there are multiple color attribute types, * and the type may change during evaluation anyway. This will also make EEVEE and Cycles - * consistent. See T93179. */ + * consistent. See #93179. */ GPUNodeLink *vertexColorLink; diff --git a/source/blender/nodes/texture/nodes/node_texture_common.cc b/source/blender/nodes/texture/nodes/node_texture_common.cc index 988195d852a..7811f00ce33 100644 --- a/source/blender/nodes/texture/nodes/node_texture_common.cc +++ b/source/blender/nodes/texture/nodes/node_texture_common.cc @@ -69,7 +69,7 @@ static void group_copy_inputs(bNode *gnode, bNodeStack **in, bNodeStack *gstack) if (node->type == NODE_GROUP_INPUT) { for (sock = static_cast(node->outputs.first), a = 0; sock; sock = sock->next, a++) { - if (in[a]) { /* shouldn't need to check this T36694. */ + if (in[a]) { /* shouldn't need to check this #36694. */ ns = node_get_socket_stack(gstack, sock); if (ns) { copy_stack(ns, in[a]); @@ -95,7 +95,7 @@ static void group_copy_outputs(bNode *gnode, bNodeStack **out, bNodeStack *gstac int a; LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &group_output_node->inputs, a) { if (!out[a]) { - /* shouldn't need to check this T36694. */ + /* shouldn't need to check this #36694. */ continue; } diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index cb8dd0a8bc2..bf60e27d967 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -109,7 +109,7 @@ void BPY_context_update(struct bContext *C); /** * Use for `CTX_*_set(..)` functions need to set values which are later read back as expected. * In this case we don't want the Python context to override the values as it causes problems - * see T66256. + * see #66256. * * \param dict_p: A pointer to #bContext.data.py_context so we can assign a new value. * \param dict_orig: The value of #bContext.data.py_context_orig to check if we need to copy. diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 08cdbe10233..615f05adc1b 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -727,12 +727,12 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, else { IDProperty *prop_exist; - /* avoid freeing when types match in case they are referenced by the UI, see: T37073 + /* avoid freeing when types match in case they are referenced by the UI, see: #37073 * obviously this isn't a complete solution, but helps for common cases. */ prop_exist = IDP_GetPropertyFromGroup(group, prop->name); if ((prop_exist != NULL) && (prop_exist->type == prop->type) && (prop_exist->subtype == prop->subtype)) { - /* Preserve prev/next links!!! See T42593. */ + /* Preserve prev/next links!!! See #42593. */ prop->prev = prop_exist->prev; prop->next = prop_exist->next; prop->flag = prop_exist->flag; diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 9e140bbe7bd..fc0065912b6 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -835,11 +835,11 @@ static void pyc_exception_buffer_handle_system_exit(PyObject *error_type, return; } - /* NOTE(@campbellbarton): A `SystemExit` exception will exit immediately (unless inspecting). + /* NOTE(@ideasman42): A `SystemExit` exception will exit immediately (unless inspecting). * So print the error and exit now. This is necessary as the call to #PyErr_Print exits, * the temporary `sys.stderr` assignment causes the output to be suppressed, failing silently. * Instead, restore the error and print it. If Python changes it's behavior and doesn't exit in - * the future - continue to create the exception buffer, see: T99966. + * the future - continue to create the exception buffer, see: #99966. * * Arguably accessing a `SystemExit` exception as a buffer should be supported without exiting. * (by temporarily enabling inspection for example) however - it's not obvious exactly when this diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c index 25fe31322b1..8fbbf1be12a 100644 --- a/source/blender/python/gpu/gpu_py_batch.c +++ b/source/blender/python/gpu/gpu_py_batch.c @@ -157,7 +157,7 @@ static PyObject *pygpu_batch_vertbuf_add(BPyGPUBatch *self, BPyGPUVertBuf *py_bu PyList_Append(self->references, (PyObject *)py_buf); #endif - GPU_batch_vertbuf_add(self->batch, py_buf->buf); + GPU_batch_vertbuf_add(self->batch, py_buf->buf, false); Py_RETURN_NONE; } diff --git a/source/blender/python/gpu/gpu_py_offscreen.c b/source/blender/python/gpu/gpu_py_offscreen.c index 2738a4e4784..6e50a7f323d 100644 --- a/source/blender/python/gpu/gpu_py_offscreen.c +++ b/source/blender/python/gpu/gpu_py_offscreen.c @@ -365,7 +365,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPyGPUOffScreen *self, PyObject *ar depsgraph = BKE_scene_ensure_depsgraph(G_MAIN, scene, view_layer); - /* Disable 'bgl' state since it interfere with off-screen drawing, see: T84402. */ + /* Disable 'bgl' state since it interfere with off-screen drawing, see: #84402. */ const bool is_bgl = GPU_bgl_get(); if (is_bgl) { GPU_bgl_end(); @@ -374,7 +374,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPyGPUOffScreen *self, PyObject *ar GPU_offscreen_bind(self->ofs, true); /* Cache the #GPUViewport so the frame-buffers and associated textures are - * not reallocated each time, see: T89204 */ + * not reallocated each time, see: #89204 */ if (!self->viewport) { self->viewport = GPU_viewport_create(); } diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 9352e7cc9b1..80c22bd7a97 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -269,7 +269,7 @@ static PyObject *pygpu_shader_uniform_vector_float(BPyGPUShader *self, PyObject } GPU_shader_bind(self->shader); - GPU_shader_uniform_vector(self->shader, location, length, count, pybuffer.buf); + GPU_shader_uniform_float_ex(self->shader, location, length, count, pybuffer.buf); PyBuffer_Release(&pybuffer); @@ -292,7 +292,7 @@ static PyObject *pygpu_shader_uniform_vector_int(BPyGPUShader *self, PyObject *a } GPU_shader_bind(self->shader); - GPU_shader_uniform_vector_int(self->shader, location, length, count, pybuffer.buf); + GPU_shader_uniform_int_ex(self->shader, location, length, count, pybuffer.buf); PyBuffer_Release(&pybuffer); @@ -367,7 +367,7 @@ static PyObject *pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args) } GPU_shader_bind(self->shader); - GPU_shader_uniform_vector_int(self->shader, location, length, 1, values); + GPU_shader_uniform_int_ex(self->shader, location, length, 1, values); Py_RETURN_NONE; } @@ -437,7 +437,7 @@ static PyObject *pygpu_shader_uniform_float(BPyGPUShader *self, PyObject *args) } GPU_shader_bind(self->shader); - GPU_shader_uniform_vector(self->shader, location, length, 1, values); + GPU_shader_uniform_float_ex(self->shader, location, length, 1, values); Py_RETURN_NONE; } @@ -509,7 +509,7 @@ static PyObject *pygpu_shader_uniform_int(BPyGPUShader *self, PyObject *args) } GPU_shader_bind(self->shader); - GPU_shader_uniform_vector_int(self->shader, location, length, 1, values); + GPU_shader_uniform_int_ex(self->shader, location, length, 1, values); Py_RETURN_NONE; } @@ -533,7 +533,7 @@ static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args } GPU_shader_bind(self->shader); - int slot = GPU_shader_get_texture_binding(self->shader, name); + int slot = GPU_shader_get_sampler_binding(self->shader, name); GPU_texture_bind(py_texture->tex, slot); GPU_shader_uniform_1i(self->shader, name, slot); @@ -559,7 +559,7 @@ static PyObject *pygpu_shader_uniform_block(BPyGPUShader *self, PyObject *args) return NULL; } - int binding = GPU_shader_get_uniform_block_binding(self->shader, name); + int binding = GPU_shader_get_ubo_binding(self->shader, name); if (binding == -1) { PyErr_SetString( PyExc_BufferError, diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 70cf231bc26..ccff3d5a682 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -153,7 +153,7 @@ static PyObject *make_app_info(void) SetObjItem(PyBool_FromLong(G.factory_startup)); /* build info, use bytes since we can't assume _any_ encoding: - * see patch T30154 for issue */ + * see patch #30154 for issue */ #ifdef BUILD_DATE SetBytesItem(build_date); SetBytesItem(build_time); @@ -557,7 +557,7 @@ PyObject *BPY_app_struct(void) BlenderAppType.tp_init = NULL; BlenderAppType.tp_new = NULL; BlenderAppType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ /* Kind of a hack on top of #PyStructSequence. */ py_struct_seq_getset_init(); diff --git a/source/blender/python/intern/bpy_app_alembic.c b/source/blender/python/intern/bpy_app_alembic.c index abecd3d8c1a..afa71572d5a 100644 --- a/source/blender/python/intern/bpy_app_alembic.c +++ b/source/blender/python/intern/bpy_app_alembic.c @@ -84,7 +84,7 @@ PyObject *BPY_app_alembic_struct(void) BlenderAppABCType.tp_init = NULL; BlenderAppABCType.tp_new = NULL; BlenderAppABCType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c index a744f3fd4fa..9d90b66854e 100644 --- a/source/blender/python/intern/bpy_app_build_options.c +++ b/source/blender/python/intern/bpy_app_build_options.c @@ -349,7 +349,7 @@ PyObject *BPY_app_build_options_struct(void) BlenderAppBuildOptionsType.tp_init = NULL; BlenderAppBuildOptionsType.tp_new = NULL; BlenderAppBuildOptionsType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c index c14b6672e4d..10170d5439b 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.c +++ b/source/blender/python/intern/bpy_app_ffmpeg.c @@ -126,7 +126,7 @@ PyObject *BPY_app_ffmpeg_struct(void) BlenderAppFFmpegType.tp_init = NULL; BlenderAppFFmpegType.tp_new = NULL; BlenderAppFFmpegType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 947ec5d60bb..296d10fa84b 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -242,7 +242,7 @@ PyObject *BPY_app_handlers_struct(void) BlenderAppCbType.tp_init = NULL; BlenderAppCbType.tp_new = NULL; BlenderAppCbType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ /* assign the C callbacks */ if (ret) { diff --git a/source/blender/python/intern/bpy_app_ocio.c b/source/blender/python/intern/bpy_app_ocio.c index 3f28d05830b..0cea91908c0 100644 --- a/source/blender/python/intern/bpy_app_ocio.c +++ b/source/blender/python/intern/bpy_app_ocio.c @@ -90,7 +90,7 @@ PyObject *BPY_app_ocio_struct(void) BlenderAppOCIOType.tp_init = NULL; BlenderAppOCIOType.tp_new = NULL; BlenderAppOCIOType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_oiio.c b/source/blender/python/intern/bpy_app_oiio.c index ec0bc31c844..ae1c2176dd3 100644 --- a/source/blender/python/intern/bpy_app_oiio.c +++ b/source/blender/python/intern/bpy_app_oiio.c @@ -86,7 +86,7 @@ PyObject *BPY_app_oiio_struct(void) BlenderAppOIIOType.tp_init = NULL; BlenderAppOIIOType.tp_new = NULL; BlenderAppOIIOType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_opensubdiv.c b/source/blender/python/intern/bpy_app_opensubdiv.c index 61250147d67..5ffa23789e7 100644 --- a/source/blender/python/intern/bpy_app_opensubdiv.c +++ b/source/blender/python/intern/bpy_app_opensubdiv.c @@ -82,7 +82,7 @@ PyObject *BPY_app_opensubdiv_struct(void) /* prevent user from creating new instances */ BlenderAppOpenSubdivType.tp_init = NULL; BlenderAppOpenSubdivType.tp_new = NULL; - /* without this we can't do set(sys.modules) T29635. */ + /* without this we can't do set(sys.modules) #29635. */ BlenderAppOpenSubdivType.tp_hash = (hashfunc)_Py_HashPointer; return ret; diff --git a/source/blender/python/intern/bpy_app_openvdb.c b/source/blender/python/intern/bpy_app_openvdb.c index 6cc476cebcc..91ff0cd04ce 100644 --- a/source/blender/python/intern/bpy_app_openvdb.c +++ b/source/blender/python/intern/bpy_app_openvdb.c @@ -88,7 +88,7 @@ PyObject *BPY_app_openvdb_struct(void) BlenderAppOVDBType.tp_init = NULL; BlenderAppOVDBType.tp_new = NULL; BlenderAppOVDBType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_sdl.c b/source/blender/python/intern/bpy_app_sdl.c index ff659cf43c4..6f13058b8e1 100644 --- a/source/blender/python/intern/bpy_app_sdl.c +++ b/source/blender/python/intern/bpy_app_sdl.c @@ -123,7 +123,7 @@ PyObject *BPY_app_sdl_struct(void) BlenderAppSDLType.tp_init = NULL; BlenderAppSDLType.tp_new = NULL; BlenderAppSDLType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c index ccd0228d9e4..3fa3c5d75b1 100644 --- a/source/blender/python/intern/bpy_app_translations.c +++ b/source/blender/python/intern/bpy_app_translations.c @@ -854,7 +854,7 @@ PyObject *BPY_app_translations_struct(void) /* prevent user from creating new instances */ BlenderAppTranslationsType.tp_new = NULL; - /* without this we can't do set(sys.modules) T29635. */ + /* without this we can't do set(sys.modules) #29635. */ BlenderAppTranslationsType.tp_hash = (hashfunc)_Py_HashPointer; return ret; @@ -862,7 +862,7 @@ PyObject *BPY_app_translations_struct(void) void BPY_app_translations_end(void) { - /* In case the object remains in a module's name-space, see T44127. */ + /* In case the object remains in a module's name-space, see #44127. */ #ifdef WITH_INTERNATIONAL _clear_translations_cache(); #endif diff --git a/source/blender/python/intern/bpy_app_usd.c b/source/blender/python/intern/bpy_app_usd.c index 811a4e4c085..3fcdb1aa3c7 100644 --- a/source/blender/python/intern/bpy_app_usd.c +++ b/source/blender/python/intern/bpy_app_usd.c @@ -85,7 +85,7 @@ PyObject *BPY_app_usd_struct(void) BlenderAppUSDType.tp_init = NULL; BlenderAppUSDType.tp_new = NULL; BlenderAppUSDType.tp_hash = (hashfunc) - _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ + _Py_HashPointer; /* without this we can't do set(sys.modules) #29635. */ return ret; } diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 9f2714405a9..ae19e99151b 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -211,7 +211,7 @@ static PyObject *bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph) /** * Adds a variable `depsgraph` to the name-space. This can then be used to obtain evaluated - * data-blocks, and the current view layer and scene. See T75553. + * data-blocks, and the current view layer and scene. See #75553. */ static void bpy_pydriver_namespace_update_depsgraph(struct Depsgraph *depsgraph) { @@ -346,7 +346,7 @@ static const bool secure_opcodes[255] = { OK_OP(RESUME), OK_OP(LIST_EXTEND), OK_OP(SET_UPDATE), -/* NOTE(@campbellbarton): Don't enable dict manipulation, unless we can prove there is not way it +/* NOTE(@ideasman42): Don't enable dict manipulation, unless we can prove there is not way it * can be used to manipulate the name-space (potentially allowing malicious code). */ # if 0 OK_OP(DICT_MERGE), @@ -430,7 +430,7 @@ static const bool secure_opcodes[255] = { OK_OP(STORE_DEREF), OK_OP(LIST_EXTEND), OK_OP(SET_UPDATE), -/* NOTE(@campbellbarton): Don't enable dict manipulation, unless we can prove there is not way it +/* NOTE(@ideasman42): Don't enable dict manipulation, unless we can prove there is not way it * can be used to manipulate the name-space (potentially allowing malicious code). */ # if 0 OK_OP(DICT_MERGE), @@ -560,9 +560,9 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, /* (old) NOTE: PyGILState_Ensure() isn't always called because python can call * the bake operator which intern starts a thread which calls scene update * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive() - * if #PyGILState_Ensure() is needed, see T27683. + * if #PyGILState_Ensure() is needed, see #27683. * - * (new) NOTE: checking if python is running is not thread-safe T28114 + * (new) NOTE: checking if python is running is not thread-safe #28114 * now release the GIL on python operator execution instead, using * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender. * @@ -612,7 +612,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, gilstate = PyGILState_Ensure(); } - /* Needed since drivers are updated directly after undo where `main` is re-allocated T28807. */ + /* Needed since drivers are updated directly after undo where `main` is re-allocated #28807. */ BPY_update_rna_module(); /* Initialize global dictionary for Python driver evaluation settings. */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 8f112c14bb2..4fe39e1c5b0 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -316,7 +316,7 @@ void BPY_python_start(bContext *C, int argc, const char **argv) PyPreConfig preconfig; PyStatus status; - /* To narrow down reports where the systems Python is inexplicably used, see: T98131. */ + /* To narrow down reports where the systems Python is inexplicably used, see: #98131. */ CLOG_INFO( BPY_LOG_INTERFACE, 2, @@ -329,7 +329,7 @@ void BPY_python_start(bContext *C, int argc, const char **argv) } else { /* Only use the systems environment variables and site when explicitly requested. - * Since an incorrect 'PYTHONPATH' causes difficult to debug errors, see: T72807. + * Since an incorrect 'PYTHONPATH' causes difficult to debug errors, see: #72807. * An alternative to setting `preconfig.use_environment = 0` */ PyPreConfig_InitIsolatedConfig(&preconfig); } @@ -372,9 +372,9 @@ void BPY_python_start(bContext *C, int argc, const char **argv) config.pathconfig_warnings = 0; /* Allow the user site directory because this is used - * when PIP installing packages from Blender, see: T104000. + * when PIP installing packages from Blender, see: #104000. * - * NOTE(@campbellbarton): While an argument can be made for isolating Blender's Python + * NOTE(@ideasman42): While an argument can be made for isolating Blender's Python * from the users home directory entirely, an alternative directory should be used in that * case - so PIP can be used to install packages. Otherwise PIP will install packages to a * directory which us not in the users `sys.path`, see `site.USER_BASE` for details. */ @@ -507,7 +507,7 @@ void BPY_python_start(bContext *C, int argc, const char **argv) #endif #ifdef WITH_PYTHON_MODULE - /* Disable all add-ons at exit, not essential, it just avoids resource leaks, see T71362. */ + /* Disable all add-ons at exit, not essential, it just avoids resource leaks, see #71362. */ BPY_run_string_eval(C, (const char *[]){"atexit", "addon_utils", NULL}, "atexit.register(addon_utils.disable_all)"); diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index cba9bd59abf..35a26e46be2 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -32,7 +32,7 @@ static PyObject *func_bpy_atregister = NULL; /* borrowed reference, `atexit` hol static void atexit_func_call(const char *func_name, PyObject *atexit_func_arg) { - /* NOTE(@campbellbarton): no error checking, if any of these fail we'll get a crash + /* NOTE(@ideasman42): no error checking, if any of these fail we'll get a crash * this is intended, but if its problematic it could be changed. */ PyObject *atexit_mod = PyImport_ImportModuleLevel("atexit", NULL, NULL, NULL, 0); diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c index 49f5261ba19..0ed2fc0b63c 100644 --- a/source/blender/python/intern/bpy_interface_run.c +++ b/source/blender/python/intern/bpy_interface_run.c @@ -64,7 +64,7 @@ static void bpy_text_filepath_get(char *filepath, text->id.name + 2); } -/* Very annoying! Undo #_PyModule_Clear(), see T23871. */ +/* Very annoying! Undo #_PyModule_Clear(), see #23871. */ #define PYMODULE_CLEAR_WORKAROUND #ifdef PYMODULE_CLEAR_WORKAROUND @@ -154,7 +154,7 @@ static bool python_script_exec(bContext *C, * Note on use of 'globals()', it's important not copy the dictionary because * tools may inspect 'sys.modules["__main__"]' for variables defined in the code * where using a copy of 'globals()' causes code execution - * to leave the main namespace untouched. see: T51444 + * to leave the main namespace untouched. see: #51444 * * This leaves us with the problem of variables being included, * currently this is worked around using 'dict.__del__' it's ugly but works. diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index dec4c65e48d..8777a0393da 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -91,7 +91,7 @@ * * This struct adds/removes the user-count of each #PyObject it references, * it's needed in case the function is removed from the class (unlikely but possible), - * also when an annotation evaluates to a `lambda` with Python 3.10 and newer e.g: T86332. + * also when an annotation evaluates to a `lambda` with Python 3.10 and newer e.g: #86332. * * Pointers to this struct are held in: * diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 1e338ca03b3..1c21d00ab3b 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -780,7 +780,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) return ret; } -/* NOTE(@campbellbarton): Regarding comparison `__cmp__`: +/* NOTE(@ideasman42): Regarding comparison `__cmp__`: * checking the 'ptr->data' matches works in almost all cases, * however there are a few RNA properties that are fake sub-structs and * share the pointer with the parent, in those cases this happens 'a.b == a' @@ -2264,7 +2264,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s } } /* It's important to end the iterator after `result` has been created - * so iterators may optionally invalidate items that were iterated over, see: T100286. */ + * so iterators may optionally invalidate items that were iterated over, see: #100286. */ RNA_property_collection_end(&iter); if (found) { if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) { @@ -2384,7 +2384,7 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons } } /* It's important to end the iterator after `result` has been created - * so iterators may optionally invalidate items that were iterated over, see: T100286. */ + * so iterators may optionally invalidate items that were iterated over, see: #100286. */ RNA_property_collection_end(&iter); if (found) { if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) { @@ -8152,7 +8152,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, continue; } - /* TODO(@campbellbarton): this is used for classmethod's too, + /* TODO(@ideasman42): this is used for classmethod's too, * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg. * Keep this as-is since it's working, but we should be using * 'FUNC_USE_SELF_TYPE' for many functions. */ @@ -8243,7 +8243,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, continue; } - /* TODO(@campbellbarton): Use Python3.7x _PyObject_LookupAttr(), 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); @@ -8495,7 +8495,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } #ifdef USE_PEDANTIC_WRITE - /* Handle nested draw calls, see: T89253. */ + /* Handle nested draw calls, see: #89253. */ const bool rna_disallow_writes_prev = rna_disallow_writes; rna_disallow_writes = is_readonly ? true : false; #endif diff --git a/source/blender/python/intern/bpy_rna_context.c b/source/blender/python/intern/bpy_rna_context.c index 1d033fee026..df0a10050a1 100644 --- a/source/blender/python/intern/bpy_rna_context.c +++ b/source/blender/python/intern/bpy_rna_context.c @@ -121,7 +121,7 @@ static PyObject *bpy_rna_context_temp_override_exit(BPyContextTempOverride *self bContext *C = self->context; /* Special case where the window is expected to be freed on file-read, - * in this case the window should not be restored, see: T92818. */ + * in this case the window should not be restored, see: #92818. */ bool do_restore = true; if (self->ctx_init.win) { wmWindowManager *wm = CTX_wm_manager(C); diff --git a/source/blender/python/intern/bpy_rna_driver.c b/source/blender/python/intern/bpy_rna_driver.c index a74381eb571..74d3f77b0c2 100644 --- a/source/blender/python/intern/bpy_rna_driver.c +++ b/source/blender/python/intern/bpy_rna_driver.c @@ -43,7 +43,7 @@ PyObject *pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct D const PropertyType type = RNA_property_type(prop); if (type == PROP_ENUM) { /* Note that enum's are converted to strings by default, - * we want to avoid that, see: T52213 */ + * we want to avoid that, see: #52213 */ driver_arg = PyLong_FromLong(RNA_property_enum_get(&ptr, prop)); } else { diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c index 428263fd4c4..63da19b8c9e 100644 --- a/source/blender/python/intern/bpy_traceback.c +++ b/source/blender/python/intern/bpy_traceback.c @@ -166,9 +166,9 @@ finally: bool python_script_error_jump( const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end) { - /* WARNING(@campbellbarton): The normalized exception is restored (losing line number info). + /* WARNING(@ideasman42): The normalized exception is restored (losing line number info). * Ideally this would leave the exception state as it found it, but that needs to be done - * carefully with regards to reference counting, see: T97731. */ + * carefully with regards to reference counting, see: #97731. */ bool success = false; PyObject *exception, *value; diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index d01c3d8587c..84f694c3d58 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -2696,7 +2696,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure swizzleClosure = POINTER_AS_INT(closure); /* We must first copy current vec into tvec, else some org values may be lost. - * See T31760. + * See #31760. * Assuming self->vec_num can't be higher than MAX_DIMENSIONS! */ memcpy(tvec, self->vec, self->vec_num * sizeof(float)); @@ -2708,7 +2708,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure } /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...). - * See T31760. */ + * See #31760. */ memcpy(self->vec, tvec, self->vec_num * sizeof(float)); /* continue with BaseMathObject_WriteCallback at the end */ diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index b9c1680f421..c8ecb827c6d 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -774,10 +774,10 @@ void RE_bake_pixels_populate(Mesh *me, for (int a = 0; a < 3; a++) { const float *uv = mloopuv[lt->tri[a]]; - /* NOTE(@campbellbarton): workaround for pixel aligned UVs which are common and can screw + /* NOTE(@ideasman42): workaround for pixel aligned UVs which are common and can screw * up our intersection tests where a pixel gets in between 2 faces or the middle of a quad, * camera aligned quads also have this problem but they are less common. - * Add a small offset to the UVs, fixes bug T18685. */ + * Add a small offset to the UVs, fixes bug #18685. */ vec[a][0] = (uv[0] - bk_image->uv_offset[0]) * float(bk_image->width) - (0.5f + 0.001f); vec[a][1] = (uv[1] - bk_image->uv_offset[1]) * float(bk_image->height) - (0.5f + 0.002f); } diff --git a/source/blender/render/intern/texture_image.c b/source/blender/render/intern/texture_image.c index 60a769348e8..8c7d842ee47 100644 --- a/source/blender/render/intern/texture_image.c +++ b/source/blender/render/intern/texture_image.c @@ -220,7 +220,7 @@ int imagewrap(Tex *tex, } } - /* Keep this before interpolation T29761. */ + /* Keep this before interpolation #29761. */ if (ima) { if ((tex->imaflag & TEX_USEALPHA) && (ima->alpha_mode != IMA_ALPHA_IGNORE)) { if ((tex->imaflag & TEX_CALCALPHA) == 0) { @@ -235,7 +235,7 @@ int imagewrap(Tex *tex, filterx = (0.5f * tex->filtersize) / ibuf->x; filtery = (0.5f * tex->filtersize) / ibuf->y; - /* Important that this value is wrapped T27782. + /* Important that this value is wrapped #27782. * this applies the modifications made by the checks above, * back to the floating point values */ fx -= (float)(xi - x) / (float)ibuf->x; diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index a04f1cd75c4..e0e2781b562 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -558,10 +558,10 @@ static void generate_margin(ImBuf *ibuf, for (int a = 0; a < 3; a++) { const float *uv = mloopuv[lt->tri[a]]; - /* NOTE(@campbellbarton): workaround for pixel aligned UVs which are common and can screw up + /* NOTE(@ideasman42): workaround for pixel aligned UVs which are common and can screw up * our intersection tests where a pixel gets in between 2 faces or the middle of a quad, * camera aligned quads also have this problem but they are less common. - * Add a small offset to the UVs, fixes bug T18685. */ + * Add a small offset to the UVs, fixes bug #18685. */ vec[a][0] = (uv[0] - uv_offset[0]) * float(ibuf->x) - (0.5f + 0.001f); vec[a][1] = (uv[1] - uv_offset[1]) * float(ibuf->y) - (0.5f + 0.002f); } diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index c6f4d47ac75..25f633ef27c 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -562,10 +562,10 @@ static Sequence *seq_dupli(const Scene *scene_src, /* When using SEQ_DUPE_UNIQUE_NAME, it is mandatory to add new sequences in relevant container * (scene or meta's one), *before* checking for unique names. Otherwise the meta's list is empty - * and hence we miss all seqs in that meta that have already been duplicated (see T55668). + * and hence we miss all seqs in that meta that have already been duplicated (see #55668). * Note that unique name check itself could be done at a later step in calling code, once all * seqs have bee duplicated (that was first, simpler solution), but then handling of animation - * data will be broken (see T60194). */ + * data will be broken (see #60194). */ if (new_seq_list != NULL) { BLI_addtail(new_seq_list, seqn); } diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index 7744bc4ce1c..89da6bb1769 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -314,7 +314,7 @@ Sequence *SEQ_add_sound_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL * line up with the video frames. Therefore we round this number to the * nearest frame as the audio track usually overshoots or undershoots the * end frame of the video by a little bit. - * See T47135 for under shoot example. */ + * See #47135 for under shoot example. */ seq->len = MAX2(1, round((info.length - sound->offset_time) * FPS)); Strip *strip = seq->strip; diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 1edc4b85f96..c81482c878c 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -526,7 +526,7 @@ static void seq_transform_handle_overwrite(Scene *scene, SEQ_collection_free(targets); /* Remove covered strips. This must be done in separate loop, because `SEQ_edit_strip_split()` - * also uses `SEQ_edit_remove_flagged_sequences()`. See T91096. */ + * also uses `SEQ_edit_remove_flagged_sequences()`. See #91096. */ if (SEQ_collection_len(strips_to_delete) > 0) { Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips_to_delete) { @@ -575,7 +575,7 @@ void SEQ_transform_handle_overlap(Scene *scene, } /* If any effects still overlap, we need to move them up. - * In some cases other strips can be overlapping still, see T90646. */ + * In some cases other strips can be overlapping still, see #90646. */ Sequence *seq; SEQ_ITERATOR_FOREACH (seq, transformed_strips) { if (SEQ_transform_test_overlap(scene, seqbasep, seq)) { diff --git a/source/blender/simulation/intern/SIM_mass_spring.cpp b/source/blender/simulation/intern/SIM_mass_spring.cpp index 5858e16da6e..a5413678de2 100644 --- a/source/blender/simulation/intern/SIM_mass_spring.cpp +++ b/source/blender/simulation/intern/SIM_mass_spring.cpp @@ -496,7 +496,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s) scaling = parms->bending + s->lin_stiffness * fabsf(parms->max_bend - parms->bending); kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON)); - /* Fix for T45084 for cloth stiffness must have cb proportional to kb */ + /* Fix for #45084 for cloth stiffness must have cb proportional to kb */ cb = kb * parms->bending_damping; SIM_mass_spring_force_spring_bending(data, s->ij, s->kl, s->restlen, kb, cb); @@ -515,7 +515,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s) scaling = s->lin_stiffness * parms->bending; kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON)); - /* Fix for T45084 for cloth stiffness must have cb proportional to kb */ + /* Fix for #45084 for cloth stiffness must have cb proportional to kb */ cb = kb * parms->bending_damping; /* XXX assuming same restlen for ij and jk segments here, diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index faa22e6216e..80785954a4e 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -622,7 +622,7 @@ int WM_operator_props_popup_confirm(struct bContext *C, /** * Same as #WM_operator_props_popup but call the operator first, * This way - the button values correspond to the result of the operator. - * Without this, first access to a button will make the result jump, see T32452. + * Without this, first access to a button will make the result jump, see #32452. */ int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, @@ -672,7 +672,7 @@ bool WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, sho * \param store: Store properties for re-use when an operator has finished * (unless #PROP_SKIP_SAVE is set). * - * \warning do not use this within an operator to call itself! T29537. + * \warning do not use this within an operator to call itself! #29537. */ int WM_operator_call_ex(struct bContext *C, struct wmOperator *op, bool store); int WM_operator_call(struct bContext *C, struct wmOperator *op); @@ -1619,7 +1619,7 @@ char WM_event_utf8_to_ascii(const struct wmEvent *event) ATTR_NONNULL(1) ATTR_WA * \param mval: Region relative coordinates, call with (-1, -1) resets the last cursor location. * \returns True when there was motion since last called. * - * NOTE(@campbellbarton): The logic used here isn't foolproof. + * NOTE(@ideasman42): The logic used here isn't foolproof. * It's possible that users move the cursor past #WM_EVENT_CURSOR_MOTION_THRESHOLD then back to * a position within the threshold (between mouse clicks). * In practice users never reported this since the threshold is very small (a few pixels). diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index b23b5c67b1f..4c912f379dc 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -668,7 +668,7 @@ typedef struct wmTabletData { * - The reason to differentiate between "press" and the previous event state is * the previous event may be set by key-release events. In the case of a single key click * this isn't a problem however releasing other keys such as modifiers prevents click/click-drag - * events from being detected, see: T89989. + * events from being detected, see: #89989. * * - Mouse-wheel events are excluded even though they generate #KM_PRESS * as clicking and dragging don't make sense for mouse wheel events. diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 1c0f1e03a47..4fd130cc0c4 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -514,7 +514,7 @@ static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) /* handle gizmo */ wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal; if (modal_fn) { - /* Ugly hack to ensure Python won't get 'EVT_MODAL_MAP' which isn't supported, see T73727. + /* Ugly hack to ensure Python won't get 'EVT_MODAL_MAP' which isn't supported, see #73727. * note that we could move away from wrapping modal gizmos in a modal operator, * since it's causing the need for code like this. */ wmEvent *evil_event = (wmEvent *)event; @@ -607,7 +607,7 @@ void GIZMOGROUP_OT_gizmo_tweak(wmOperatorType *ot) ot->invoke = gizmo_tweak_invoke; ot->modal = gizmo_tweak_modal; - /* TODO(@campbellbarton): This causes problems tweaking settings for operators, + /* TODO(@ideasman42): This causes problems tweaking settings for operators, * need to find a way to support this. */ #if 0 ot->flag = OPTYPE_UNDO; @@ -771,7 +771,7 @@ wmKeyMap *WM_gizmogroup_setup_keymap_generic_maybe_drag(const wmGizmoGroupType * /** * Variation of #WM_gizmogroup_keymap_common but with keymap items for selection * - * TODO(@campbellbarton): move to Python. + * TODO(@ideasman42): move to Python. * * \param name: Typically #wmGizmoGroupType.name * \param params: Typically #wmGizmoGroupType.gzmap_params @@ -784,7 +784,7 @@ static wmKeyMap *WM_gizmogroup_keymap_template_select_ex( wmKeyMap *km = WM_keymap_ensure(kc, name, params->spaceid, params->regionid); const bool do_init = BLI_listbase_is_empty(&km->items); - /* FIXME(@campbellbarton): Currently hard coded. */ + /* FIXME(@ideasman42): Currently hard coded. */ #if 0 const int select_mouse = (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE; const int select_tweak = (U.flag & USER_LMOUSESELECT) ? EVT_TWEAK_L : EVT_TWEAK_R; @@ -997,7 +997,7 @@ wmGizmoGroup *WM_gizmomaptype_group_init_runtime_with_region(wmGizmoMapType *gzm wmGizmoGroup *gzgroup = wm_gizmogroup_new_from_type(gzmap, gzgt); - /* Don't allow duplicates when switching modes for e.g. see: T66229. */ + /* Don't allow duplicates when switching modes for e.g. see: #66229. */ LISTBASE_FOREACH (wmGizmoGroup *, gzgroup_iter, &gzmap->groups) { if (gzgroup_iter->type == gzgt) { if (gzgroup_iter != gzgroup) { @@ -1053,7 +1053,7 @@ void WM_gizmomaptype_group_unlink(bContext *C, WM_gizmomaptype_group_free(gzgt_ref); } - /* TODO(@campbellbarton): Gizmos may share key-maps, for now don't + /* TODO(@ideasman42): Gizmos may share key-maps, for now don't * remove however we could flag them as temporary/owned by the gizmo. */ #if 0 /* NOTE: we may want to keep this key-map for editing. */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 627ff1a0d9a..03fb91c95d8 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -259,7 +259,7 @@ bool WM_gizmomap_minmax(const wmGizmoMap *gzmap, * \param poll: Polling function for excluding gizmos. * \param data: Custom data passed to \a poll * - * TODO(@campbellbarton): this uses unreliable order, + * TODO(@ideasman42): this uses unreliable order, * best we use an iterator function instead of a hash. */ static GHash *WM_gizmomap_gizmo_hash_new(const bContext *C, @@ -430,7 +430,7 @@ static void gizmos_draw_list(const wmGizmoMap *gzmap, const bContext *C, ListBas return; } - /* TODO(@campbellbarton): This will need it own shader probably? + /* TODO(@ideasman42): This will need it own shader probably? * Don't think it can be handled from that point though. */ // const bool use_lighting = (U.gizmo_flag & V3D_GIZMO_SHADED) != 0; @@ -501,7 +501,7 @@ static void gizmo_draw_select_3d_loop(const bContext *C, bool *r_use_select_bias) { - /* TODO(@campbellbarton): this depends on depth buffer being written to, + /* TODO(@ideasman42): this depends on depth buffer being written to, * currently broken for the 3D view. */ bool is_depth_prev = false; bool is_depth_skip_prev = false; @@ -576,7 +576,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, /* TODO: waiting for the GPU in the middle of the event loop for every * mouse move is bad for performance, we need to find a solution to not - * use the GPU or draw something once. (see T61474) */ + * use the GPU or draw something once. (see #61474) */ GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0); /* do the drawing */ gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index aad7cc6ac93..671a69003dd 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -619,7 +619,7 @@ void wm_close_and_free_all(bContext *C, ListBase *wmlist) BLI_remlink(wmlist, wm); /* Don't handle user counts as this is only ever called once #G_MAIN has already been freed via * #BKE_main_free so any ID's referenced by the window-manager (from ID properties) will crash. - * See: T100703. */ + * See: #100703. */ BKE_libblock_free_data(&wm->id, false); BKE_libblock_free_data_py(&wm->id); MEM_freeN(wm); diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 74e760013fd..94f0d79a3a5 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -291,7 +291,7 @@ void WM_cursor_grab_disable(wmWindow *win, const int mouse_ungrab_xy[2]) static void wm_cursor_warp_relative(wmWindow *win, int x, int y) { - /* NOTE: don't use wmEvent coords because of continuous grab T36409. */ + /* NOTE: don't use wmEvent coords because of continuous grab #36409. */ int cx, cy; wm_cursor_position_get(win, &cx, &cy); WM_cursor_warp(win, cx + x, cy + y); diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc index 4b4b516f0b9..7b0056cc987 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.cc +++ b/source/blender/windowmanager/intern/wm_dragdrop.cc @@ -694,7 +694,7 @@ void WM_drag_free_imported_drag_ID(Main *bmain, wmDrag *drag, wmDropBox *drop) bmain, drop->ptr, static_cast(asset_drag->id_type)); if (id != nullptr) { /* Do not delete the dragged ID if it has any user, otherwise if it is a 're-used' ID it will - * cause T95636. Note that we need first to add the user that we want to remove in + * cause #95636. Note that we need first to add the user that we want to remove in * #BKE_id_free_us. */ id_us_plus(id); BKE_id_free_us(bmain, id); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 241c476faea..ebe670bfa21 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -132,7 +132,7 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region) * deltas without it escaping from the window. In this case we never want to show the actual * cursor coordinates so limit reading the cursor location to when the cursor is grabbed and * wrapping in a region since this is the case when it would otherwise attempt to draw the - * cursor outside the view/window. See: T102792. */ + * cursor outside the view/window. See: #102792. */ if ((WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) && wm_window_grab_warp_region_is_set(win)) { int x = 0, y = 0; @@ -842,13 +842,13 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend) int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR); int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon"); int rect_geo_loc = GPU_shader_get_uniform(shader, "rect_geom"); - int texture_bind_loc = GPU_shader_get_texture_binding(shader, "image"); + int texture_bind_loc = GPU_shader_get_sampler_binding(shader, "image"); GPU_texture_bind(texture, texture_bind_loc); - GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, rectt); - GPU_shader_uniform_vector(shader, rect_geo_loc, 4, 1, rectg); - GPU_shader_uniform_vector(shader, color_loc, 4, 1, (const float[4]){1, 1, 1, 1}); + GPU_shader_uniform_float_ex(shader, rect_tex_loc, 4, 1, rectt); + GPU_shader_uniform_float_ex(shader, rect_geo_loc, 4, 1, rectg); + GPU_shader_uniform_float_ex(shader, color_loc, 4, 1, (const float[4]){1, 1, 1, 1}); GPUBatch *quad = GPU_batch_preset_quad(); GPU_batch_set_shader(quad, shader); @@ -1206,7 +1206,7 @@ static void wm_draw_surface(bContext *C, wmSurface *surface) uint *WM_window_pixels_read_offscreen(bContext *C, wmWindow *win, int r_size[2]) { - /* NOTE(@campbellbarton): There is a problem reading the windows front-buffer after redrawing + /* NOTE(@ideasman42): There is a problem reading the windows front-buffer after redrawing * the window in some cases (typically to clear UI elements such as menus or search popup). * With EGL `eglSurfaceAttrib(..)` may support setting the `EGL_SWAP_BEHAVIOR` attribute to * `EGL_BUFFER_PRESERVED` however not all implementations support this. @@ -1214,7 +1214,7 @@ uint *WM_window_pixels_read_offscreen(bContext *C, wmWindow *win, int r_size[2]) * not to initialize at all. * Confusingly there are some cases where this *does* work, depending on the state of the window * and prior calls to swap-buffers, however ensuring the state exactly as needed to satisfy a - * particular GPU back-end is fragile, see T98462. + * particular GPU back-end is fragile, see #98462. * * So provide an alternative to #WM_window_pixels_read that avoids using the front-buffer. */ @@ -1362,8 +1362,8 @@ void wm_draw_update(bContext *C) GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin); if (state == GHOST_kWindowStateMinimized) { - /* do not update minimized windows, gives issues on Intel (see T33223) - * and AMD (see T50856). it seems logical to skip update for invisible + /* do not update minimized windows, gives issues on Intel (see #33223) + * and AMD (see #50856). it seems logical to skip update for invisible * window anyway. */ continue; diff --git a/source/blender/windowmanager/intern/wm_event_query.c b/source/blender/windowmanager/intern/wm_event_query.c index a1d94c33f27..2e1afe808ad 100644 --- a/source/blender/windowmanager/intern/wm_event_query.c +++ b/source/blender/windowmanager/intern/wm_event_query.c @@ -236,7 +236,7 @@ bool WM_event_is_modal_drag_exit(const wmEvent *event, } else { /* If the initial event wasn't a drag event then - * ignore #USER_RELEASECONFIRM setting: see T26756. */ + * ignore #USER_RELEASECONFIRM setting: see #26756. */ if (init_event_val != KM_CLICK_DRAG) { return 1; } @@ -582,7 +582,7 @@ int WM_event_absolute_delta_y(const struct wmEvent *event) * Most OS's use `Ctrl+Space` / `OsKey+Space` to switch IME, * so don't type in the space character. * - * \note Shift is excluded from this check since it prevented typing `Shift+Space`, see: T85517. + * \note Shift is excluded from this check since it prevented typing `Shift+Space`, see: #85517. */ bool WM_event_is_ime_switch(const struct wmEvent *event) { diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index bd8fa98cb6b..52e0f43567e 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -92,7 +92,7 @@ * Without tools using press events which would prevent click/drag events getting to the gizmos. * * This is not a fool proof solution since it's possible the gizmo operators would pass - * through these events when called, see: T65479. + * through these events when called, see: #65479. */ #define USE_GIZMO_MOUSE_PRIORITY_HACK @@ -434,7 +434,7 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file) if (wm->is_interface_locked) { return; } - /* Combine data-masks so one window doesn't disable UVs in another T26448. */ + /* Combine data-masks so one window doesn't disable UVs in another #26448. */ CustomData_MeshMasks win_combine_v3d_datamask = {0}; LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { const Scene *scene = WM_window_get_active_scene(win); @@ -450,7 +450,7 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file) Main *bmain = CTX_data_main(C); /* Copied to set's in scene_update_tagged_recursive() */ scene->customdata_mask = win_combine_v3d_datamask; - /* XXX, hack so operators can enforce data-masks T26482, GPU render. */ + /* XXX, hack so operators can enforce data-masks #26482, GPU render. */ CustomData_MeshMasks_update(&scene->customdata_mask, &scene->customdata_mask_modal); /* TODO(sergey): For now all dependency graphs which are evaluated from * workspace are considered active. This will work all fine with "locked" @@ -509,7 +509,7 @@ void wm_event_do_notifiers(bContext *C) /* Ensure inside render boundary. */ GPU_render_begin(); - /* Run the timer before assigning `wm` in the unlikely case a timer loads a file, see T80028. */ + /* Run the timer before assigning `wm` in the unlikely case a timer loads a file, see #80028. */ wm_event_execute_timers(C); wmWindowManager *wm = CTX_wm_manager(C); @@ -566,7 +566,7 @@ void wm_event_do_notifiers(bContext *C) bScreen *ref_screen = BKE_workspace_layout_screen_get( static_cast(note->reference)); - /* Free popup handlers only T35434. */ + /* Free popup handlers only #35434. */ UI_popup_handlers_remove_all(C, &win->modalhandlers); ED_screen_change(C, ref_screen); /* XXX: hum, think this over! */ @@ -789,7 +789,7 @@ static eHandlerActionFlag wm_handler_ui_call(bContext *C, } /* Don't block file-select events. Those are triggered by a separate file browser window. - * See T75292. */ + * See #75292. */ if (event->type == EVT_FILESELECT) { return WM_HANDLER_CONTINUE; } @@ -1144,8 +1144,8 @@ static void wm_operator_finished(bContext *C, else if (has_undo_step) { /* An undo step was added but the operator wasn't registered (and won't register it's self), * therefor a redo panel wouldn't redo this action but the previous registered action, - * causing the "redo" to remove/loose this operator. See: T101743. - * Register check is needed so nested operator calls don't clear the HUD. See: T103587. */ + * causing the "redo" to remove/loose this operator. See: #101743. + * Register check is needed so nested operator calls don't clear the HUD. See: #103587. */ if (!(has_register || do_register)) { if (repeat == 0) { hud_status = CLEAR; @@ -1228,7 +1228,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons } } - /* XXX(@mont29): Disabled the repeat check to address part 2 of T31840. + /* XXX(@mont29): Disabled the repeat check to address part 2 of #31840. * Carefully checked all calls to wm_operator_exec and WM_operator_repeat, don't see any reason * why this was needed, but worth to note it in case something turns bad. */ if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED) /* && repeat == 0 */) { @@ -2572,7 +2572,7 @@ static eHandlerActionFlag wm_handler_operator_call(bContext *C, wmGizmoGroup *gzgroup = WM_gizmomaptype_group_init_runtime_with_region( gzmap_type, gzgt, region); /* We can't rely on drawing to initialize gizmo's since disabling - * overlays/gizmos will prevent pre-drawing setup calls. (see T60905) */ + * overlays/gizmos will prevent pre-drawing setup calls. (see #60905) */ WM_gizmogroup_ensure_init(C, gzgroup); } } @@ -2782,7 +2782,7 @@ static eHandlerActionFlag wm_handler_fileselect_do(bContext *C, if (handler->op->reports->list.first) { - /* FIXME(@campbellbarton): temp setting window, this is really bad! + /* FIXME(@ideasman42): temp setting window, this is really bad! * only have because lib linking errors need to be seen by users :( * it can be removed without breaking anything but then no linking errors. */ wmWindow *win_prev = CTX_wm_window(C); @@ -3059,7 +3059,7 @@ static eHandlerActionFlag wm_handlers_do_gizmo_handler(bContext *C, wmGizmo *gz = wm_gizmomap_highlight_get(gzmap); /* Needed so UI blocks over gizmos don't let events fall through to the gizmos, - * noticeable for the node editor - where dragging on a node should move it, see: T73212. + * noticeable for the node editor - where dragging on a node should move it, see: #73212. * note we still allow for starting the gizmo drag outside, then travel 'inside' the node. */ if (region->type->clip_gizmo_events_by_ui) { if (UI_region_block_find_mouse_over(region, event->xy, true)) { @@ -3245,7 +3245,7 @@ static eHandlerActionFlag wm_handlers_do_intern(bContext *C, * NOTE: check 'handlers->first' because in rare cases the handlers can be cleared * by the event that's called, for eg: * - * Calling a python script which changes the area.type, see T32232. */ + * Calling a python script which changes the area.type, see #32232. */ for (wmEventHandler *handler_base = static_cast(handlers->first), *handler_base_next; handler_base && handlers->first; @@ -3422,7 +3422,7 @@ static eHandlerActionFlag wm_handlers_do(bContext *C, wmEvent *event, ListBase * if (ISMOUSE_MOTION(event->type)) { /* Test for #KM_CLICK_DRAG events. */ - /* NOTE(@campbellbarton): Needed so drag can be used for editors that support both click + /* NOTE(@ideasman42): Needed so drag can be used for editors that support both click * selection and passing through the drag action to box select. See #WM_generic_select_modal. * Unlike click, accept `action` when break isn't set. * Operators can return `OPERATOR_FINISHED | OPERATOR_PASS_THROUGH` which results @@ -3495,7 +3495,7 @@ static eHandlerActionFlag wm_handlers_do(bContext *C, wmEvent *event, ListBase * if (win->event_queue_check_drag) { if ((event->prev_press_type != event->type) && (ISKEYMODIFIER(event->type) || (event->type == event->prev_press_keymodifier))) { - /* Support releasing modifier keys without canceling the drag event, see T89989. */ + /* Support releasing modifier keys without canceling the drag event, see #89989. */ } else { CLOG_INFO( @@ -3562,7 +3562,7 @@ static eHandlerActionFlag wm_handlers_do(bContext *C, wmEvent *event, ListBase * } else if (ISMOUSE_WHEEL(event->type) || ISMOUSE_GESTURE(event->type)) { /* Modifiers which can trigger click event's, - * however we don't want this if the mouse wheel has been used, see T74607. */ + * however we don't want this if the mouse wheel has been used, see #74607. */ if (wm_action_not_handled(action)) { /* Pass. */ } @@ -3725,7 +3725,7 @@ static bool wm_event_pie_filter(wmWindow *win, const wmEvent *event) * In this case event handling exits early, however when "Load UI" is disabled * the even will still be in #wmWindow.event_queue. * - * Without this it's possible to continuously handle the same event, see: T76484. + * Without this it's possible to continuously handle the same event, see: #76484. */ static void wm_event_free_and_remove_from_queue_if_valid(wmEvent *event) { @@ -4063,7 +4063,7 @@ void wm_event_do_handlers(bContext *C) action |= wm_event_do_handlers_area_regions(C, event, area); - /* File-read case (Python), T29489. */ + /* File-read case (Python), #29489. */ if (CTX_wm_window(C) == nullptr) { wm_event_free_and_remove_from_queue_if_valid(event); GPU_render_end(); @@ -4109,7 +4109,7 @@ void wm_event_do_handlers(bContext *C) } /* If the drag even was handled, don't attempt to keep re-handing the same - * drag event on every cursor motion, see: T87511. */ + * drag event on every cursor motion, see: #87511. */ if (win->event_queue_check_drag_handled) { win->event_queue_check_drag = false; win->event_queue_check_drag_handled = false; @@ -4405,7 +4405,7 @@ wmEventHandler_Keymap *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap * allowing both the fallback-tool and active-tool to be activated * providing the key-map is configured so the keys don't conflict. * For example one mouse button can run the active-tool, another button for the fallback-tool. - * See T72567. + * See #72567. * * Follow #wmEventHandler_KeymapDynamicFn signature. */ @@ -4421,7 +4421,7 @@ static void wm_event_get_keymap_from_toolsystem_ex(wmWindowManager *wm, const char *keymap_id_list[ARRAY_SIZE(km_result->keymaps)]; int keymap_id_list_len = 0; - /* NOTE(@campbellbarton): If `win` is nullptr, this function may not behave as expected. + /* NOTE(@ideasman42): If `win` is nullptr, this function may not behave as expected. * Assert since this should not happen in practice. * If it does, the window could be looked up in `wm` using the `area`. * Keep nullptr checks in run-time code since any crashes here are difficult to redo. */ @@ -5247,7 +5247,7 @@ static void wm_event_state_update_and_click_set_ex(wmEvent *event, event_state->type = event->type; /* It's important only to write into the `event_state` modifier for keyboard * events because emulate MMB clears one of the modifiers in `event->modifier`, - * making the second press not behave as if the modifier is pressed, see T96279. */ + * making the second press not behave as if the modifier is pressed, see #96279. */ if (is_keyboard) { event_state->modifier = event->modifier; } @@ -5359,7 +5359,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, const int type, event.prev_val = event.val; /* Always use modifiers from the active window since - * changes to modifiers aren't sent to inactive windows, see: T66088. */ + * changes to modifiers aren't sent to inactive windows, see: #66088. */ if ((wm->winactive != win) && (wm->winactive && wm->winactive->eventstate)) { event.modifier = wm->winactive->eventstate->modifier; event.keymodifier = wm->winactive->eventstate->keymodifier; @@ -5556,7 +5556,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, const int type, } if (event.utf8_buf[0]) { - /* NOTE(@campbellbarton): Detect non-ASCII characters stored in `utf8_buf`, + /* NOTE(@ideasman42): Detect non-ASCII characters stored in `utf8_buf`, * ideally this would never happen but it can't be ruled out for X11 which has * special handling of Latin1 when building without UTF8 support. * Avoid regressions by adding this conversions, it should eventually be removed. */ @@ -5580,7 +5580,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, const int type, } } - /* NOTE(@campbellbarton): Setting the modifier state based on press/release + /* NOTE(@ideasman42): Setting the modifier state based on press/release * is technically incorrect. * * - The user might hold both left/right modifier keys, then only release one. diff --git a/source/blender/windowmanager/intern/wm_files.cc b/source/blender/windowmanager/intern/wm_files.cc index c5ad58d96ef..c4903f3ff23 100644 --- a/source/blender/windowmanager/intern/wm_files.cc +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -194,7 +194,7 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) ED_screen_exit(C, win, WM_window_get_active_screen(win)); } - /* NOTE(@campbellbarton): Clear the message bus so it's always cleared on file load. + /* NOTE(@ideasman42): Clear the message bus so it's always cleared on file load. * Otherwise it's cleared when "Load UI" is set (see #USER_FILENOUI & #wm_close_and_free). * However it's _not_ cleared when the UI is kept. This complicates use from add-ons * which can re-register subscribers on file-load. To support this use case, @@ -220,7 +220,7 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) * causing use-after-free error in later handling of the button callbacks in UI code * (see ui_apply_but_funcs_after()). * Tried solving this by always nullptr-ing context's menu when setting wm/win/etc., - * but it broke popups refreshing (see T47632), + * but it broke popups refreshing (see #47632), * so for now just handling this specific case here. */ CTX_wm_menu_set(C, nullptr); @@ -329,7 +329,7 @@ static void wm_window_match_replace_by_file_wm(bContext *C, * #Main.wm.first memory address in-place, while swapping all of it's contents. * * This is needed so items such as key-maps can be held by an add-on, - * without it pointing to invalid memory, see: T86431 */ + * without it pointing to invalid memory, see: #86431 */ { /* Referencing the window-manager pointer from elsewhere in the file is highly unlikely * however it's possible with ID-properties & animation-drivers. @@ -387,7 +387,7 @@ static void wm_window_match_replace_by_file_wm(bContext *C, } } } - /* make sure at least one window is kept open so we don't lose the context, check T42303 */ + /* make sure at least one window is kept open so we don't lose the context, check #42303 */ if (!has_match) { wm_window_substitute_old(oldwm, wm, @@ -473,7 +473,7 @@ static void wm_init_userdef(Main *bmain) UI_init_userdef(); - /* needed so loading a file from the command line respects user-pref T26156. */ + /* needed so loading a file from the command line respects user-pref #26156. */ SET_FLAG_FROM_TEST(G.fileflags, U.flag & USER_FILENOUI, G_FILE_NO_UI); /* set the python auto-execute setting from user prefs */ @@ -1100,7 +1100,7 @@ void wm_homefile_read_ex(bContext *C, /* Currently this only impacts preferences as it doesn't make much sense to keep the default * startup open in the case the app-template doesn't happen to define it's own startup. * Unlike preferences where we might want to only reset the app-template part of the preferences - * so as not to reset the preferences for all other Blender instances, see: T96427. */ + * so as not to reset the preferences for all other Blender instances, see: #96427. */ const bool use_factory_settings_app_template_only = params_homefile->use_factory_settings_app_template_only; const bool use_empty_data = params_homefile->use_empty_data; @@ -1168,7 +1168,7 @@ void wm_homefile_read_ex(bContext *C, if (CTX_py_init_get(C)) { /* This is restored by 'wm_file_read_post', disable before loading any preferences * so an add-on can read their own preferences when un-registering, - * and use new preferences if/when re-registering, see T67577. + * and use new preferences if/when re-registering, see #67577. * * Note that this fits into 'wm_file_read_pre' function but gets messy * since we need to know if 'reset_app_template' is true. */ @@ -1815,10 +1815,10 @@ static bool wm_file_write(bContext *C, BKE_lib_override_library_main_operations_create(bmain, true, nullptr); /* NOTE: Ideally we would call `WM_redraw_windows` here to remove any open menus. - * But we can crash if saving from a script, see T92704 & T97627. + * But we can crash if saving from a script, see #92704 & #97627. * Just checking `!G.background && BLI_thread_is_main()` is not sufficient to fix this. * Additionally some EGL configurations don't support reading the front-buffer - * immediately after drawing, see: T98462. In that case off-screen drawing is necessary. */ + * immediately after drawing, see: #98462. In that case off-screen drawing is necessary. */ /* don't forget not to return without! */ WM_cursor_wait(true); @@ -1827,7 +1827,7 @@ static bool wm_file_write(bContext *C, /* Blend file thumbnail. * * - Save before exiting edit-mode, otherwise evaluated-mesh for shared data gets corrupted. - * See T27765. + * See #27765. * - Main can store a '.blend' thumbnail, * useful for background-mode or thumbnail customization. */ @@ -1947,7 +1947,7 @@ static void wm_autosave_location(char filepath[FILE_MAX]) } const char *tempdir_base = BKE_tempdir_base(); - /* NOTE(@campbellbarton): It's strange that this is only used on WIN32. + /* NOTE(@ideasman42): It's strange that this is only used on WIN32. * From reading commits it seems accessing the temporary directory used to be less reliable. * If this is still the case on WIN32 - other features such as copy-paste will also fail. * We could support #BLENDER_USER_AUTOSAVE on all platforms or remove it entirely. */ @@ -3162,7 +3162,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* NOTE(@campbellbarton): only check this for file-path properties so saving an already + /* NOTE(@ideasman42): only check this for file-path properties so saving an already * saved file never fails with an error. * Even though this should never happen, there may be some corner case where a malformed * path is stored in `G.main->filepath`: when the file path is initialized from recovering @@ -3288,7 +3288,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent * /* if we're saving for the first time and prefer relative paths - * any existing paths will be absolute, - * enable the option to remap paths to avoid confusion T37240. */ + * enable the option to remap paths to avoid confusion #37240. */ const char *blendfile_path = BKE_main_blendfile_path_from_global(); if ((blendfile_path[0] == '\0') && (U.flag & USER_RELPATHS)) { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "relative_remap"); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index bb03c2c1413..fecbcca3c90 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -326,7 +326,7 @@ static void draw_filled_lasso(wmGesture *gt) IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); GPU_shader_bind(state.shader); - GPU_shader_uniform_vector( + GPU_shader_uniform_float_ex( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); immDrawPixelsTexTiled( diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c index e3892933905..ae8c446bd87 100644 --- a/source/blender/windowmanager/intern/wm_gesture_ops.c +++ b/source/blender/windowmanager/intern/wm_gesture_ops.c @@ -330,7 +330,7 @@ static void gesture_circle_apply(bContext *C, wmOperator *op) /* When 'wait_for_input' is false, * use properties to get the selection state (typically tool settings). - * This is done so executing as a mode can select & de-select, see: T58594. */ + * This is done so executing as a mode can select & de-select, see: #58594. */ if (gesture->wait_for_input) { gesture_modal_state_to_operator(op, gesture->modal_state); } diff --git a/source/blender/windowmanager/intern/wm_init_exit.cc b/source/blender/windowmanager/intern/wm_init_exit.cc index 577f148576a..243480c84e6 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.cc +++ b/source/blender/windowmanager/intern/wm_init_exit.cc @@ -249,7 +249,7 @@ void WM_init(bContext *C, int argc, const char **argv) BLT_lang_init(); /* Must call first before doing any `.blend` file reading, - * since versioning code may create new IDs. See T57066. */ + * since versioning code may create new IDs. See #57066. */ BLT_lang_set(nullptr); /* Init icons before reading .blend files for preview icons, which can @@ -270,7 +270,7 @@ void WM_init(bContext *C, int argc, const char **argv) BLI_assert((G.fileflags & G_FILE_NO_UI) == 0); /** - * NOTE(@campbellbarton): Startup file and order of initialization. + * NOTE(@ideasman42): Startup file and order of initialization. * * Loading #BLENDER_STARTUP_FILE, #BLENDER_USERPREF_FILE, starting Python and other sub-systems, * have inter-dependencies, for example. @@ -278,7 +278,7 @@ void WM_init(bContext *C, int argc, const char **argv) * - Some sub-systems depend on the preferences (initializing icons depend on the theme). * - Add-ons depends on the preferences to know what has been enabled. * - Add-ons depends on the window-manger to register their key-maps. - * - Evaluating the startup file depends on Python for animation-drivers (see T89046). + * - Evaluating the startup file depends on Python for animation-drivers (see #89046). * - Starting Python depends on the startup file so key-maps can be added in the window-manger. * * Loading preferences early, then application subsystems and finally the startup data would @@ -485,12 +485,12 @@ void WM_exit_ex(bContext *C, const bool do_python) #if defined(WITH_PYTHON) && !defined(WITH_PYTHON_MODULE) /* Without this, we there isn't a good way to manage false-positive resource leaks - * where a #PyObject references memory allocated with guarded-alloc, T71362. + * where a #PyObject references memory allocated with guarded-alloc, #71362. * * This allows add-ons to free resources when unregistered (which is good practice anyway). * * Don't run this code when built as a Python module as this runs when Python is in the - * process of shutting down, where running a snippet like this will crash, see T82675. + * process of shutting down, where running a snippet like this will crash, see #82675. * Instead use the `atexit` module, installed by #BPY_python_start */ const char *imports[2] = {"addon_utils", nullptr}; BPY_run_string_eval(C, imports, "addon_utils.disable_all()"); @@ -631,7 +631,7 @@ void WM_exit_ex(bContext *C, const bool do_python) BLI_task_scheduler_exit(); /* No need to call this early, rather do it late so that other - * pieces of Blender using sound may exit cleanly, see also T50676. */ + * pieces of Blender using sound may exit cleanly, see also #50676. */ BKE_sound_exit(); BKE_appdir_exit(); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index c6513a908cf..9e4e0603537 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -102,7 +102,7 @@ static void wm_keymap_item_properties_set(wmKeyMapItem *kmi) /** * Similar to #wm_keymap_item_properties_set - * but checks for the #wmOperatorType having changed, see T38042. + * but checks for the #wmOperatorType having changed, see #38042. */ static void wm_keymap_item_properties_update_ot(wmKeyMapItem *kmi) { @@ -652,13 +652,13 @@ static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km) /* add item */ if (kmdi->add_item) { - /* Do not re-add an already existing keymap item! See T42088. */ - /* We seek only for exact copy here! See T42137. */ + /* Do not re-add an already existing keymap item! See #42088. */ + /* We seek only for exact copy here! See #42137. */ wmKeyMapItem *kmi_add = wm_keymap_find_item_equals(km, kmdi->add_item); /** If kmi_add is same as kmi_remove (can happen in some cases, * typically when we got kmi_remove from #wm_keymap_find_item_equals_result()), - * no need to add or remove anything, see T45579. */ + * no need to add or remove anything, see #45579. */ /** * \note This typically happens when we apply user-defined keymap diff to a base one that @@ -1313,7 +1313,7 @@ static wmKeyMapItem *wm_keymap_item_find_in_keymap(wmKeyMap *keymap, const struct wmKeyMapItemFind_Params *params) { LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { - /* skip disabled keymap items [T38447] */ + /* skip disabled keymap items [#38447] */ if (kmi->flag & KMI_INACTIVE) { continue; } @@ -1566,7 +1566,7 @@ static wmKeyMapItem *wm_keymap_item_find(const bContext *C, * Otherwise: * * If non-strict, unset properties always match set ones in IDP_EqualsProperties_ex. * * If strict, unset properties never match set ones in IDP_EqualsProperties_ex, - * and we do not want that to change (else we get things like T41757)! + * and we do not want that to change (else we get things like #41757)! * ...so in either case, re-running a comparison with unset props set to default is useless. */ if (!found && properties) { diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index d7a01419450..b90c110efbb 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -384,7 +384,7 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event) retval = opm->type->modal(C, opm, event); OPERATOR_RETVAL_CHECK(retval); - /* if we're halfway through using a tool and cancel it, clear the options T37149. */ + /* if we're halfway through using a tool and cancel it, clear the options #37149. */ if (retval & OPERATOR_CANCELLED) { WM_operator_properties_clear(opm->ptr); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 61c03505c9b..94b34212933 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -504,7 +504,7 @@ static const char *wm_context_member_from_ptr(const bContext *C, } case ID_MA: { # define ID_CAST_OBMATACT(id_pt) \ - (BKE_object_material_get(((Object *)id_pt), ((Object *)id_pt)->actcol)) + BKE_object_material_get(((Object *)id_pt), ((Object *)id_pt)->actcol) CTX_TEST_PTR_ID_CAST( C, "object", "object.active_material", ID_CAST_OBMATACT, ptr->owner_id); break; @@ -1437,7 +1437,7 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2) uiBlock *block = arg2; /* Explicitly set UI_RETURN_OK flag, otherwise the menu might be canceled - * in case WM_operator_call_ex exits/reloads the current file (T49199). */ + * in case WM_operator_call_ex exits/reloads the current file (#49199). */ UI_popup_menu_retval_set(block, UI_RETURN_OK, true); @@ -1473,7 +1473,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *region, void *userD /* clear so the OK button is left alone */ UI_block_func_set(block, NULL, NULL, NULL); - /* new column so as not to interfere with custom layouts T26436. */ + /* new column so as not to interfere with custom layouts #26436. */ { uiLayout *col = uiLayoutColumn(layout, false); uiBlock *col_block = uiLayoutGetBlock(col); @@ -3327,7 +3327,7 @@ static void redraw_timer_step(bContext *C, static bool redraw_timer_poll(bContext *C) { /* Check background mode as many of these actions use redrawing. - * NOTE(@campbellbarton): if it's useful to support undo or animation step this could + * NOTE(@ideasman42): if it's useful to support undo or animation step this could * be allowed at the moment this seems like a corner case that isn't needed. */ return !G.background && WM_operator_winactive(C); } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 6378c756d4f..31c0dfcceb0 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -650,7 +650,7 @@ static void build_pict_list_ex( } else { /* Load images into cache until the cache is full, - * this resolves choppiness for images that are slow to load, see: T81751. */ + * this resolves choppiness for images that are slow to load, see: #81751. */ #ifdef USE_FRAME_CACHE_LIMIT bool fill_cache = true; #else diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c index 16e5f983bea..1bcd51ed9c7 100644 --- a/source/blender/windowmanager/intern/wm_splash_screen.c +++ b/source/blender/windowmanager/intern/wm_splash_screen.c @@ -179,7 +179,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE /* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized * with the OS when the splash shows, window clipping in this case gives - * ugly results and clipping the splash isn't useful anyway, just disable it T32938. */ + * ugly results and clipping the splash isn't useful anyway, just disable it #32938. */ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index 48a0d47f26a..6487fd97820 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -291,7 +291,7 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op) else if (win_src->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) { const bScreen *screen = WM_window_get_active_screen(win_src); - /* ED_workspace_layout_duplicate() can't handle other cases yet T44688 */ + /* ED_workspace_layout_duplicate() can't handle other cases yet #44688 */ if (screen->state != SCREENNORMAL) { BKE_report( op->reports, RPT_ERROR, "Failed to switch to Time Sequential mode when in fullscreen"); @@ -334,7 +334,7 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - /* Without this, the popup won't be freed properly, see T44688. */ + /* Without this, the popup won't be freed properly, see #44688. */ CTX_wm_window_set(C, win_src); win_src->stereo3d_format->display_mode = prev_display_mode; return OPERATOR_CANCELLED; diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index 6e08f607bae..1a6aa974a7b 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -561,7 +561,7 @@ void WM_toolsystem_refresh_active(bContext *C) workspace->id.tag &= ~LIB_TAG_DOIT; /* Refresh to ensure data is initialized. * This is needed because undo can load a state which no longer has the underlying DNA data - * needed for the tool (un-initialized paint-slots for eg), see: T64339. */ + * needed for the tool (un-initialized paint-slots for eg), see: #64339. */ LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { toolsystem_refresh_ref(C, workspace, tref); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 0f8940d75be..46213bea120 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -85,7 +85,7 @@ /** * When windows are activated, simulate modifier press/release to match the current state of - * held modifier keys, see T40317. + * held modifier keys, see #40317. */ #define USE_WIN_ACTIVATE @@ -98,8 +98,8 @@ * reported as not being held. Since this is standard behavior for Linux/MS-Window, * opt to use this. * - * NOTE(@campbellbarton): Events generated for non-active windows are rare, - * this happens when using the mouse-wheel over an unfocused window, see: T103722. + * NOTE(@ideasman42): Events generated for non-active windows are rare, + * this happens when using the mouse-wheel over an unfocused window, see: #103722. */ #define USE_WIN_DEACTIVATE @@ -212,8 +212,8 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win) return; } - /* Prevents non-drawable state of main windows (bugs T22967, - * T25071 and possibly T22477 too). Always clear it even if + /* Prevents non-drawable state of main windows (bugs #22967, + * #25071 and possibly #22477 too). Always clear it even if * this window was not the drawable one, because we mess with * drawing context to discard the GW context. */ wm_window_clear_drawable(wm); @@ -632,7 +632,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, wm_window_swap_buffers(win); - /* Clear double buffer to avoids flickering of new windows on certain drivers. (See T97600) */ + /* Clear double buffer to avoids flickering of new windows on certain drivers. (See #97600) */ GPU_clear_color(0.55f, 0.55f, 0.55f, 1.0f); // GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified); @@ -666,7 +666,7 @@ static void wm_window_ghostwindow_ensure(wmWindowManager *wm, wmWindow *win, boo wm_init_state.override_flag &= ~WIN_OVERRIDE_WINSTATE; } - /* without this, cursor restore may fail, T45456 */ + /* without this, cursor restore may fail, #45456 */ if (win->cursor == 0) { win->cursor = WM_CURSOR_DEFAULT; } @@ -1150,7 +1150,7 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt const uint8_t keymodifier_eventstate = win->eventstate->modifier; const uint8_t keymodifier_l = wm_ghost_modifier_query(MOD_SIDE_LEFT); const uint8_t keymodifier_r = wm_ghost_modifier_query(MOD_SIDE_RIGHT); - /* NOTE(@campbellbarton): when non-zero, there are modifiers held in + /* NOTE(@ideasman42): when non-zero, there are modifiers held in * `win->eventstate` which are not considered held by the GHOST internal state. * While this should not happen, it's important all modifier held in event-state * receive release events. Without this, so any events generated while the window @@ -1286,7 +1286,7 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt wm_window_make_drawable(wm, win); #if 0 - /* NOTE(@campbellbarton): Ideally we could swap-buffers to avoid a full redraw. + /* NOTE(@ideasman42): Ideally we could swap-buffers to avoid a full redraw. * however this causes window flickering on resize with LIBDECOR under WAYLAND. */ wm_window_swap_buffers(win); #else @@ -2134,7 +2134,7 @@ uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2]) { /* WARNING: Reading from the front-buffer immediately after drawing may fail, * for a slower but more reliable version of this function #WM_window_pixels_read_offscreen - * should be preferred. See it's comments for details on why it's needed, see also T98462. */ + * should be preferred. See it's comments for details on why it's needed, see also #98462. */ bool setup_context = wm->windrawable != win; if (setup_context) { diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index da8ec0ef82a..0b31b13cef1 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -69,7 +69,7 @@ void wm_homefile_read(struct bContext *C, /** * Special case, support deferred execution of #wm_file_read_post, - * Needed when loading for the first time to workaround order of initialization bug, see T89046. + * Needed when loading for the first time to workaround order of initialization bug, see #89046. */ void wm_homefile_read_post(struct bContext *C, const struct wmFileReadPost_Params *params_file_read_post); diff --git a/source/creator/creator.c b/source/creator/creator.c index 431c0c2e56f..fe6d501164a 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -301,7 +301,7 @@ int main(int argc, /* Un-buffered `stdout` makes `stdout` and `stderr` better synchronized, and helps * when stepping through code in a debugger (prints are immediately * visible). However disabling buffering causes lock contention on windows - * see T76767 for details, since this is a debugging aid, we do not enable + * see #76767 for details, since this is a debugging aid, we do not enable * the un-buffered behavior for release builds. */ #ifndef NDEBUG setvbuf(stdout, NULL, _IONBF, 0); @@ -584,9 +584,13 @@ int main(int argc, } WM_main(C); } -#endif /* WITH_PYTHON_MODULE */ + /* Neither #WM_exit, #WM_main return, this quiets CLANG's `unreachable-code-return` warning. */ + BLI_assert_unreachable(); + +#endif /* !WITH_PYTHON_MODULE */ return 0; + } /* End of `int main(...)` function. */ #ifdef WITH_PYTHON_MODULE diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 7eb37982086..41708cc81a8 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -478,6 +478,7 @@ static int arg_handle_print_version(int UNUSED(argc), { print_version_full(); exit(0); + BLI_assert_unreachable(); return 0; } @@ -684,6 +685,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo # endif exit(0); + BLI_assert_unreachable(); return 0; } @@ -1236,6 +1238,7 @@ static int arg_handle_env_system_set(int argc, const char **argv, void *UNUSED(d if (argc < 2) { fprintf(stderr, "%s requires one argument\n", argv[0]); exit(1); + BLI_assert_unreachable(); } for (; *ch_src; ch_src++, ch_dst++) { @@ -1722,7 +1725,7 @@ static int arg_handle_scene_set(int argc, const char **argv, void *data) if (scene) { CTX_data_scene_set(C, scene); - /* Set the scene of the first window, see: T55991, + /* Set the scene of the first window, see: #55991, * otherwise scripts that run later won't get this scene back from the context. */ wmWindow *win = CTX_wm_window(C); if (win == NULL) { diff --git a/tests/performance/api/device.py b/tests/performance/api/device.py index fb11c5948e6..1e0766cf72b 100644 --- a/tests/performance/api/device.py +++ b/tests/performance/api/device.py @@ -39,7 +39,6 @@ def get_gpu_device(args: None) -> List: if device.type == device_type: result.append({'type': device.type, 'name': device.name, 'index': index}) index += 1 - break return result diff --git a/tests/python/alembic_export_tests.py b/tests/python/alembic_export_tests.py index 95ae3ee9feb..4fb04405d05 100644 --- a/tests/python/alembic_export_tests.py +++ b/tests/python/alembic_export_tests.py @@ -396,7 +396,7 @@ class UVMapExportTest(AbstractAlembicTest): def test_uvmap_export(self, tempdir: pathlib.Path): """Minimal test for exporting multiple UV maps on an animated mesh. - This covers the issue reported in T77021. + This covers the issue reported in #77021. """ basename = 'T77021-multiple-uvmaps-animated-mesh' abc = tempdir / f'{basename}.abc' diff --git a/tests/python/bl_id_management.py b/tests/python/bl_id_management.py index 9ca53b4214b..c29640d01e7 100644 --- a/tests/python/bl_id_management.py +++ b/tests/python/bl_id_management.py @@ -173,7 +173,7 @@ class TestIdRename(TestHelper, unittest.TestCase): data = dt break data.name = name - # This can fail currently, see T71244. + # This can fail currently, see #71244. # ~ self.assertEqual(data.name, self.default_name + ".001") self.ensure_proper_order() diff --git a/tests/python/bl_keymap_completeness.py b/tests/python/bl_keymap_completeness.py index 97335a94c01..1d16cf752a7 100644 --- a/tests/python/bl_keymap_completeness.py +++ b/tests/python/bl_keymap_completeness.py @@ -36,7 +36,7 @@ def check_maps(): # Keymap functions of tools are not in blender anyway... continue print("\t%s" % km_id) - # TODO T65963, broken keymap hierarchy tests disabled until fixed. + # TODO #65963, broken keymap hierarchy tests disabled until fixed. # err = True test = maps_bl - maps_py @@ -45,7 +45,7 @@ def check_maps(): for km_id in test: km = keyconf.keymaps[km_id] print(" ('%s', '%s', '%s', [])," % (km_id, km.space_type, km.region_type)) - # TODO T65963, broken keymap hierarchy tests disabled until fixed. + # TODO #65963, broken keymap hierarchy tests disabled until fixed. # err = True # Check space/region's are OK diff --git a/tests/python/bl_rigging_symmetrize.py b/tests/python/bl_rigging_symmetrize.py index 10ba99ac6e9..035560b624e 100644 --- a/tests/python/bl_rigging_symmetrize.py +++ b/tests/python/bl_rigging_symmetrize.py @@ -153,12 +153,12 @@ class ArmatureSymmetrizeTest(AbstractAnimationTest, unittest.TestCase): bpy.ops.wm.open_mainfile(filepath=str( self.testdir / "symm_test.blend")) - # T81541 (D9214) + # #81541 (D9214) arm = bpy.data.objects['transform_const_rig'] expected_arm = bpy.data.objects['expected_transform_const_rig'] self.assertEqualSymmetrize(arm, expected_arm) - # T66751 (D6009) + # #66751 (D6009) arm = bpy.data.objects['dragon_rig'] expected_arm = bpy.data.objects['expected_dragon_rig'] self.assertEqualSymmetrize(arm, expected_arm) diff --git a/tests/python/bl_rna_manual_reference.py b/tests/python/bl_rna_manual_reference.py index 958cc46ae29..7636c91b802 100644 --- a/tests/python/bl_rna_manual_reference.py +++ b/tests/python/bl_rna_manual_reference.py @@ -4,13 +4,15 @@ # ./blender.bin --background -noaudio --python tests/python/bl_rna_manual_reference.py # # 1) test_data() -- ensure the data we have is correct format -# 2) test_lookup_coverage() -- ensure that we have lookups for _every_ RNA path +# 2) test_lookup_coverage() -- ensure that we have lookups for _every_ RNA path and all patterns are used. # 3) test_urls() -- ensure all the URL's are correct # 4) test_language_coverage() -- ensure language lookup table is complete # import bpy +VERBOSE = False + def test_data(): import rna_manual_reference @@ -28,6 +30,21 @@ def test_data(): raise +def lookup_rna_url(rna_id, visit_indices): + """ + A local version of ``WM_OT_doc_view_manual._lookup_rna_url`` + that tracks which matches are found. + """ + import rna_manual_reference + from fnmatch import fnmatchcase + rna_id = rna_id.lower() + for i, (pattern, url_suffix) in enumerate(rna_manual_reference.url_manual_mapping): + if fnmatchcase(rna_id, pattern): + visit_indices.add(i) + return rna_manual_reference.url_manual_prefix + url_suffix + return None + + # a stripped down version of api_dump() in rna_info_dump.py def test_lookup_coverage(): @@ -51,14 +68,35 @@ def test_lookup_coverage(): set_group_all = set() set_group_doc = set() + visit_indices = set() + + print("") + print("----------------------------------") + print("RNA Patterns Unknown to the Manual") + for rna_group, rna_id in rna_ids(): - url = wm.WM_OT_doc_view_manual._lookup_rna_url(rna_id, verbose=False) - print(rna_id, "->", url) + # Correct but slower & doesn't track usage. + # url = wm.WM_OT_doc_view_manual._lookup_rna_url(rna_id, verbose=False) + url = lookup_rna_url(rna_id, visit_indices) + + if VERBOSE: + print(rna_id, "->", url) + else: + print(rna_id) set_group_all.add(rna_group) if url is not None: set_group_doc.add(rna_group) + print("") + print("---------------------------------------") + print("Unused RNA Patterns Known to the Manual") + + import rna_manual_reference + for i, (pattern, url_suffix) in enumerate(rna_manual_reference.url_manual_mapping): + if i not in visit_indices: + print(pattern, url_suffix) + # finally report undocumented groups print("") print("---------------------") @@ -103,13 +141,16 @@ def test_urls(): if LOCAL_PREFIX: for url in sorted(urls): url_full = os.path.join(LOCAL_PREFIX, url.partition("#")[0]) - print(" %s ... " % url_full, end="") if os.path.exists(url_full): - print(color_green + "OK" + color_normal) + if VERBOSE: + print(" %s ... " % url_full, end="") + print(color_green + "OK" + color_normal) else: + print(" %s ... " % url_full, end="") print(color_red + "FAIL!" + color_normal) urls_fail.append(url) - else: + elif False: + # URL lookups are too slow to be practical. for url in sorted(urls): url_full = prefix + url print(" %s ... " % url_full, end="") @@ -120,6 +161,8 @@ def test_urls(): except urllib.error.HTTPError: print(color_red + "FAIL!" + color_normal) urls_fail.append(url) + else: + print("Skipping URL lookups, define LOCAL_PREFIX env variable, and point it to a manual build!") if urls_fail: urls_len = "%d" % len(urls_fail) diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py index 1d30a696e98..36eceb0558d 100644 --- a/tests/python/cycles_render_tests.py +++ b/tests/python/cycles_render_tests.py @@ -139,7 +139,7 @@ def main(): else: report.set_compare_engine('cycles', 'CPU') - # Increase threshold for motion blur, see T78777. + # Increase threshold for motion blur, see #78777. test_dir_name = Path(test_dir).name if test_dir_name == 'motion_blur': report.set_fail_threshold(0.032) diff --git a/tests/python/operators.py b/tests/python/operators.py index 884910e159c..da05ee59dbf 100644 --- a/tests/python/operators.py +++ b/tests/python/operators.py @@ -549,7 +549,7 @@ def main(): ), - # T87259 - test cases + # #87259 - test cases SpecMeshTest( "CubeEdgeUnsubdivide", "testCubeEdgeUnsubdivide", "expectedCubeEdgeUnsubdivide", [OperatorSpecEditMode("unsubdivide", {}, "EDGE", {i for i in range(6)})], diff --git a/tests/python/pep8.py b/tests/python/pep8.py index 6b046f5a6af..79547d1635e 100644 --- a/tests/python/pep8.py +++ b/tests/python/pep8.py @@ -29,6 +29,8 @@ def file_list_py(path): for dirpath, dirnames, filenames in os.walk(path): dirnames[:] = [d for d in dirnames if not d.startswith(".")] for filename in filenames: + if filename.startswith("."): + continue if filename.endswith((".py", ".cfg")): yield os.path.join(dirpath, filename) diff --git a/tests/python/view_layer/test_evaluation_render_settings_a.py b/tests/python/view_layer/test_evaluation_render_settings_a.py index 526e7462716..732877aa288 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_a.py +++ b/tests/python/view_layer/test_evaluation_render_settings_a.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_b.py b/tests/python/view_layer/test_evaluation_render_settings_b.py index 1674ae6a93e..9eef7973322 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_b.py +++ b/tests/python/view_layer/test_evaluation_render_settings_b.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_c.py b/tests/python/view_layer/test_evaluation_render_settings_c.py index ca572253dff..7159a725f99 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_c.py +++ b/tests/python/view_layer/test_evaluation_render_settings_c.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_d.py b/tests/python/view_layer/test_evaluation_render_settings_d.py index 2c2173af0d6..3ef70d45f39 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_d.py +++ b/tests/python/view_layer/test_evaluation_render_settings_d.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_e.py b/tests/python/view_layer/test_evaluation_render_settings_e.py index f2cc6f579d7..d14c42b3ff6 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_e.py +++ b/tests/python/view_layer/test_evaluation_render_settings_e.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_f.py b/tests/python/view_layer/test_evaluation_render_settings_f.py index 966bdbd4392..56a41c2d5a6 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_f.py +++ b/tests/python/view_layer/test_evaluation_render_settings_f.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_g.py b/tests/python/view_layer/test_evaluation_render_settings_g.py index dfc34e76975..91f03ef7973 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_g.py +++ b/tests/python/view_layer/test_evaluation_render_settings_g.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_h.py b/tests/python/view_layer/test_evaluation_render_settings_h.py index 0e3bc5faaa8..ed6965face6 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_h.py +++ b/tests/python/view_layer/test_evaluation_render_settings_h.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct diff --git a/tests/python/view_layer/test_evaluation_render_settings_i.py b/tests/python/view_layer/test_evaluation_render_settings_i.py index d44e00ae665..958f78ea3dc 100644 --- a/tests/python/view_layer/test_evaluation_render_settings_i.py +++ b/tests/python/view_layer/test_evaluation_render_settings_i.py @@ -16,7 +16,7 @@ from view_layer_common import * # ############################################################ class UnitTesting(ViewLayerTesting): - @unittest.skip("Uses the clay engine, that is removed T55454") + @unittest.skip("Uses the clay engine, that is removed #55454") def test_render_settings(self): """ See if the depsgraph evaluation is correct