diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 00000000000..548af935888 --- /dev/null +++ b/.arcconfig @@ -0,0 +1,8 @@ +{ + "project_id" : "Blender", + "conduit_uri" : "https://developer.blender.org/", + "phabricator.uri" : "https://developer.blender.org/", + "git.default-relative-commit" : "origin/master", + "arc.land.update.default" : "rebase", + "arc.land.onto.default" : "master" +} diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index dab4417109a..b5da14a63d1 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later ## Update and uncomment this in the release branch -# set(BLENDER_VERSION 3.1) +set(BLENDER_VERSION 3.5) function(download_source dep) set(TARGET_FILE ${${dep}_FILE}) diff --git a/build_files/build_environment/cmake/epoxy.cmake b/build_files/build_environment/cmake/epoxy.cmake index 28dd8a70f26..da9c204d5ec 100644 --- a/build_files/build_environment/cmake/epoxy.cmake +++ b/build_files/build_environment/cmake/epoxy.cmake @@ -10,7 +10,7 @@ ExternalProject_Add(external_epoxy URL_HASH ${EPOXY_HASH_TYPE}=${EPOXY_HASH} PREFIX ${BUILD_DIR}/epoxy PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/epoxy/src/external_epoxy/ < ${PATCH_DIR}/epoxy.diff - CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${MESON} setup --prefix ${LIBDIR}/epoxy --default-library ${EPOXY_LIB_TYPE} --libdir lib ${BUILD_DIR}/epoxy/src/external_epoxy-build ${BUILD_DIR}/epoxy/src/external_epoxy -Dtests=false ${MESON_BUILD_TYPE} + CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${MESON} setup --prefix ${LIBDIR}/epoxy --default-library ${EPOXY_LIB_TYPE} --libdir lib ${BUILD_DIR}/epoxy/src/external_epoxy-build ${BUILD_DIR}/epoxy/src/external_epoxy -Dtests=false BUILD_COMMAND ninja INSTALL_COMMAND ninja install ) diff --git a/build_files/build_environment/cmake/fribidi.cmake b/build_files/build_environment/cmake/fribidi.cmake index e1dd6287d12..9d83191741f 100644 --- a/build_files/build_environment/cmake/fribidi.cmake +++ b/build_files/build_environment/cmake/fribidi.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(external_fribidi URL_HASH ${FRIBIDI_HASH_TYPE}=${FRIBIDI_HASH} DOWNLOAD_DIR ${DOWNLOAD_DIR} PREFIX ${BUILD_DIR}/fribidi - CONFIGURE_COMMAND ${MESON} setup --prefix ${LIBDIR}/fribidi ${MESON_BUILD_TYPE} -Ddocs=false --default-library static --libdir lib ${BUILD_DIR}/fribidi/src/external_fribidi-build ${BUILD_DIR}/fribidi/src/external_fribidi + CONFIGURE_COMMAND ${MESON} setup --prefix ${LIBDIR}/fribidi -Ddocs=false --default-library static --libdir lib ${BUILD_DIR}/fribidi/src/external_fribidi-build ${BUILD_DIR}/fribidi/src/external_fribidi BUILD_COMMAND ninja INSTALL_COMMAND ninja install INSTALL_DIR ${LIBDIR}/fribidi diff --git a/build_files/build_environment/cmake/harfbuzz.cmake b/build_files/build_environment/cmake/harfbuzz.cmake index 67dccf487b3..5f57ab6c0ff 100644 --- a/build_files/build_environment/cmake/harfbuzz.cmake +++ b/build_files/build_environment/cmake/harfbuzz.cmake @@ -21,7 +21,6 @@ set(HARFBUZZ_EXTRA_OPTIONS # Only used for command line utilities, # disable as this would add an addition & unnecessary build-dependency. -Dcairo=disabled - ${MESON_BUILD_TYPE} ) ExternalProject_Add(external_harfbuzz @@ -60,10 +59,3 @@ if(BUILD_MODE STREQUAL Release AND WIN32) DEPENDEES install ) endif() - -if(BUILD_MODE STREQUAL Debug AND WIN32) - ExternalProject_Add_Step(external_harfbuzz after_install - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/harfbuzz/lib/libharfbuzz.a ${HARVEST_TARGET}/harfbuzz/lib/libharfbuzz_d.lib - DEPENDEES install - ) -endif() diff --git a/build_files/build_environment/cmake/mesa.cmake b/build_files/build_environment/cmake/mesa.cmake index c60acaaaa35..ab07c09cc00 100644 --- a/build_files/build_environment/cmake/mesa.cmake +++ b/build_files/build_environment/cmake/mesa.cmake @@ -15,7 +15,7 @@ llvm-config = '${LIBDIR}/llvm/bin/llvm-config'" ) set(MESA_EXTRA_FLAGS - ${MESON_BUILD_TYPE} + -Dbuildtype=release -Dc_args=${MESA_CFLAGS} -Dcpp_args=${MESA_CXXFLAGS} -Dc_link_args=${MESA_LDFLAGS} diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 34861caf8fc..0a7548f95fb 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -16,10 +16,8 @@ message("BuildMode = ${BUILD_MODE}") if(BUILD_MODE STREQUAL "Debug") set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Debug) - set(MESON_BUILD_TYPE -Dbuildtype=debug) else() set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Release) - set(MESON_BUILD_TYPE -Dbuildtype=release) endif() set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files") diff --git a/build_files/build_environment/cmake/wayland.cmake b/build_files/build_environment/cmake/wayland.cmake index 4160de2bfa8..ab573a8dca9 100644 --- a/build_files/build_environment/cmake/wayland.cmake +++ b/build_files/build_environment/cmake/wayland.cmake @@ -13,7 +13,7 @@ ExternalProject_Add(external_wayland # NOTE: `-lm` is needed for `libxml2` which is a static library that uses `libm.so`, # without this, math symbols such as `floor` aren't found. CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:${LIBDIR}/ffi/lib/pkgconfig:$PKG_CONFIG_PATH - ${MESON} --prefix ${LIBDIR}/wayland ${MESON_BUILD_TYPE} -Ddocumentation=false -Dtests=false -D "c_link_args=-L${LIBDIR}/ffi/lib -lm" . ../external_wayland + ${MESON} --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -D "c_link_args=-L${LIBDIR}/ffi/lib -lm" . ../external_wayland BUILD_COMMAND ninja INSTALL_COMMAND ninja install ) diff --git a/build_files/build_environment/cmake/wayland_protocols.cmake b/build_files/build_environment/cmake/wayland_protocols.cmake index b588419df01..708d9adba1e 100644 --- a/build_files/build_environment/cmake/wayland_protocols.cmake +++ b/build_files/build_environment/cmake/wayland_protocols.cmake @@ -7,7 +7,7 @@ ExternalProject_Add(external_wayland_protocols PREFIX ${BUILD_DIR}/wayland-protocols # Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own WAYLAND. CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/wayland/lib64/pkgconfig:$PKG_CONFIG_PATH - ${MESON} --prefix ${LIBDIR}/wayland-protocols ${MESON_BUILD_TYPE} . ../external_wayland_protocols -Dtests=false + ${MESON} --prefix ${LIBDIR}/wayland-protocols . ../external_wayland_protocols -Dtests=false BUILD_COMMAND ninja INSTALL_COMMAND ninja install ) diff --git a/build_files/build_environment/cmake/xvidcore.cmake b/build_files/build_environment/cmake/xvidcore.cmake index e319408ca15..f64d00f4c4a 100644 --- a/build_files/build_environment/cmake/xvidcore.cmake +++ b/build_files/build_environment/cmake/xvidcore.cmake @@ -17,13 +17,11 @@ ExternalProject_Add(external_xvidcore INSTALL_DIR ${LIBDIR}/xvidcore ) -if(WIN32) - ExternalProject_Add_Step(external_xvidcore after_install - COMMAND ${CMAKE_COMMAND} -E rename ${LIBDIR}/xvidcore/lib/xvidcore.a ${LIBDIR}/xvidcore/lib/libxvidcore.a || true - COMMAND ${CMAKE_COMMAND} -E remove ${LIBDIR}/xvidcore/lib/xvidcore.dll.a - DEPENDEES install - ) -endif() +ExternalProject_Add_Step(external_xvidcore after_install + COMMAND ${CMAKE_COMMAND} -E rename ${LIBDIR}/xvidcore/lib/xvidcore.a ${LIBDIR}/xvidcore/lib/libxvidcore.a || true + COMMAND ${CMAKE_COMMAND} -E remove ${LIBDIR}/xvidcore/lib/xvidcore.dll.a + DEPENDEES install +) if(MSVC) set_target_properties(external_xvidcore PROPERTIES FOLDER Mingw) diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake index 10805728574..08cb882ebfb 100644 --- a/build_files/cmake/config/blender_release.cmake +++ b/build_files/cmake/config/blender_release.cmake @@ -85,7 +85,7 @@ if(NOT APPLE) set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE) set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE) set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE) - set(WITH_CYCLES_HIP_BINARIES OFF CACHE BOOL "" FORCE) + set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE) set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE) set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE) endif() diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index 401dab442e0..12f92235b2a 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -142,7 +142,7 @@ def cmake_advanced_info() -> Union[Tuple[List[str], List[Tuple[str, str]]], Tupl make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM") if make_exe is None: - print("Make command not found: CMAKE_MAKE_PROGRAM") + print("Make command not found in: %r not found" % project_path) return None, None make_exe_basename = os.path.basename(make_exe) diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml index 0576d0c0a1e..6bade75e70f 100644 --- a/build_files/config/pipeline_config.yaml +++ b/build_files/config/pipeline_config.yaml @@ -5,38 +5,38 @@ update-code: git: submodules: - - branch: main + - branch: blender-v3.5-release commit_id: HEAD path: release/scripts/addons - - branch: main + - branch: blender-v3.5-release commit_id: HEAD path: release/scripts/addons_contrib - - branch: main + - branch: blender-v3.5-release commit_id: HEAD path: release/datafiles/locale - - branch: main + - branch: blender-v3.5-release commit_id: HEAD path: source/tools svn: libraries: darwin-arm64: - branch: trunk + branch: tags/blender-3.5-release commit_id: HEAD path: lib/darwin_arm64 darwin-x86_64: - branch: trunk + branch: tags/blender-3.5-release commit_id: HEAD path: lib/darwin linux-x86_64: - branch: trunk + branch: tags/blender-3.5-release commit_id: HEAD path: lib/linux_x86_64_glibc_228 windows-amd64: - branch: trunk + branch: tags/blender-3.5-release commit_id: HEAD path: lib/win64_vc15 tests: - branch: trunk + branch: tags/blender-3.5-release commit_id: HEAD path: lib/tests benchmarks: diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index 27e3e5b3a11..aa321462cf7 100755 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -52,11 +52,9 @@ def get_blender_git_root() -> str: # Setup for precompiled libraries and tests from svn. -def get_effective_architecture(args: argparse.Namespace) -> str: - architecture = args.architecture - if architecture: - assert isinstance(architecture, str) - return architecture +def get_effective_architecture(args: argparse.Namespace): + if args.architecture: + return args.architecture # Check platform.version to detect arm64 with x86_64 python binary. if "ARM64" in platform.version(): @@ -275,7 +273,7 @@ if __name__ == "__main__": major = blender_version.version // 100 minor = blender_version.version % 100 branch = f"blender-v{major}.{minor}-release" - release_version: Optional[str] = f"{major}.{minor}" + release_version = f"{major}.{minor}" else: branch = 'main' release_version = None diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index a9fa740805d..e1d8ac39bcf 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = Blender # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = V3.6 +PROJECT_NUMBER = V3.5 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 78543258349..41eacb7417f 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1676,20 +1676,17 @@ class CyclesPreferences(bpy.types.AddonPreferences): col.label(text="and NVIDIA driver version %s or newer" % driver_version, icon='BLANK1', translate=False) elif device_type == 'HIP': - if True: - col.label(text="HIP temporarily disabled due to compiler bugs", icon='BLANK1') - else: - import sys - if sys.platform[:3] == "win": - driver_version = "21.Q4" - col.label(text="Requires AMD GPU with Vega or RDNA architecture", 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 Vega or RDNA architecture", icon='BLANK1') - col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1', - translate=False) + import sys + if sys.platform[:3] == "win": + driver_version = "21.Q4" + col.label(text="Requires AMD GPU with Vega or RDNA architecture", 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 Vega or RDNA architecture", 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"): diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index b10aeec8bdf..4b165e1a5be 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -42,15 +42,12 @@ endif() ########################################################################### if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP) - set(WITH_CYCLES_HIP_BINARIES OFF) - message(STATUS "HIP temporarily disabled due to compiler bugs") + find_package(HIP) + set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES) - # find_package(HIP) - # set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES) - - # if(HIP_FOUND) - # message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})") - # endif() + if(HIP_FOUND) + message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})") + endif() endif() if(NOT WITH_HIP_DYNLOAD) diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h index e60f2fa4c31..0fc7ed655d3 100644 --- a/intern/cycles/kernel/integrator/state_template.h +++ b/intern/cycles/kernel/integrator/state_template.h @@ -122,7 +122,7 @@ KERNEL_STRUCT_MEMBER(guiding, bool, use_surface_guiding, KERNEL_FEATURE_PATH_GUI KERNEL_STRUCT_MEMBER(guiding, float, sample_surface_guiding_rand, KERNEL_FEATURE_PATH_GUIDING) /* The probability to use surface guiding (i.e., diffuse sampling prob * guiding prob)*/ KERNEL_STRUCT_MEMBER(guiding, float, surface_guiding_sampling_prob, KERNEL_FEATURE_PATH_GUIDING) -/* Probability of sampling a BSSRDF closure instead of a BSDF closure. */ +/* Probability of sampling a BSSRDF closure instead of a BSDF closure*/ KERNEL_STRUCT_MEMBER(guiding, float, bssrdf_sampling_prob, KERNEL_FEATURE_PATH_GUIDING) /* If volume guiding is enabled */ KERNEL_STRUCT_MEMBER(guiding, bool, use_volume_guiding, KERNEL_FEATURE_PATH_GUIDING) diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 2b9e356e0de..3c5698b4218 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -1177,7 +1177,7 @@ void LightManager::device_update(Device *device, void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background) { - /* TODO: check if the light tree member variables need to be wrapped in a conditional too. */ + /* to-do: check if the light tree member variables need to be wrapped in a conditional too*/ dscene->light_tree_nodes.free(); dscene->light_tree_emitters.free(); dscene->light_to_tree.free(); diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 843f6f62c73..066ff4aa03a 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -306,23 +306,14 @@ static void gwl_window_frame_update_from_pending(GWL_Window *win); #ifdef USE_EVENT_BACKGROUND_THREAD enum eGWL_PendingWindowActions { - /** - * The state of the window frame has changed, apply the state from #GWL_Window::frame_pending. - */ - PENDING_WINDOW_FRAME_CONFIGURE = 0, - /** The EGL buffer must be resized to match #GWL_WindowFrame::size. */ - PENDING_EGL_WINDOW_RESIZE, + PENDING_FRAME_CONFIGURE = 0, + PENDING_EGL_RESIZE, # ifdef GHOST_OPENGL_ALPHA - /** Draw an opaque region behind the window. */ PENDING_OPAQUE_SET, # endif - /** - * The DPI for a monitor has changed or the monitors (outputs) - * this window is visible on may have changed. Recalculate the windows scale. - */ - PENDING_OUTPUT_SCALE_UPDATE, + PENDING_SCALE_UPDATE, }; -# define PENDING_NUM (PENDING_OUTPUT_SCALE_UPDATE + 1) +# define PENDING_NUM (PENDING_SCALE_UPDATE + 1) static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWindowActions type) { @@ -332,10 +323,10 @@ static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWin static void gwl_window_pending_actions_handle(GWL_Window *win) { - if (win->pending_actions[PENDING_WINDOW_FRAME_CONFIGURE].exchange(false)) { + if (win->pending_actions[PENDING_FRAME_CONFIGURE].exchange(false)) { gwl_window_frame_update_from_pending(win); } - if (win->pending_actions[PENDING_EGL_WINDOW_RESIZE].exchange(false)) { + if (win->pending_actions[PENDING_EGL_RESIZE].exchange(false)) { wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0); } # ifdef GHOST_OPENGL_ALPHA @@ -343,7 +334,7 @@ static void gwl_window_pending_actions_handle(GWL_Window *win) win->ghost_window->setOpaque(); } # endif - if (win->pending_actions[PENDING_OUTPUT_SCALE_UPDATE].exchange(false)) { + if (win->pending_actions[PENDING_SCALE_UPDATE].exchange(false)) { win->ghost_window->outputs_changed_update_scale(); } } @@ -351,10 +342,9 @@ static void gwl_window_pending_actions_handle(GWL_Window *win) #endif /* USE_EVENT_BACKGROUND_THREAD */ /** - * Update the window's #GWL_WindowFrame. - * The caller must handle locking & run from the main thread. + * Update the window's #GWL_WindowFrame */ -static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win) +static void gwl_window_frame_update_from_pending_lockfree(GWL_Window *win) { #ifdef USE_EVENT_BACKGROUND_THREAD GHOST_ASSERT(win->ghost_system->main_thread_id == std::this_thread::get_id(), @@ -391,7 +381,7 @@ static void gwl_window_frame_update_from_pending(GWL_Window *win) #ifdef USE_EVENT_BACKGROUND_THREAD std::lock_guard lock_frame_guard{win->frame_pending_mutex}; #endif - gwl_window_frame_update_from_pending_no_lock(win); + gwl_window_frame_update_from_pending_lockfree(win); } /** \} */ @@ -586,12 +576,12 @@ static void frame_handle_configure(struct libdecor_frame *frame, GHOST_SystemWayland *system = win->ghost_system; const bool is_main_thread = system->main_thread_id == std::this_thread::get_id(); if (!is_main_thread) { - gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE); + gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE); } else # endif { - gwl_window_frame_update_from_pending_no_lock(win); + gwl_window_frame_update_from_pending_lockfree(win); } } } @@ -681,7 +671,7 @@ static void xdg_surface_handle_configure(void *data, if (!is_main_thread) { /* NOTE(@ideasman42): this only gets one redraw, * I could not find a case where this causes problems. */ - gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE); + gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE); } else #endif @@ -1383,7 +1373,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale() { #ifdef USE_EVENT_BACKGROUND_THREAD if (system_->main_thread_id != std::this_thread::get_id()) { - gwl_window_pending_actions_tag(window_, PENDING_OUTPUT_SCALE_UPDATE); + gwl_window_pending_actions_tag(window_, PENDING_SCALE_UPDATE); return false; } #endif diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index ccd2980d77e..3e82f55c583 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -93,7 +93,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, } RECT win_rect = {left, top, long(left + width), long(top + height)}; - adjustWindowRectForDesktop(&win_rect, style, extended_style); + adjustWindowRectForClosestMonitor(&win_rect, style, extended_style); wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0); m_hWnd = ::CreateWindowExW(extended_style, /* window extended style */ @@ -298,55 +298,24 @@ GHOST_WindowWin32::~GHOST_WindowWin32() m_directManipulationHelper = NULL; } -void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle) +void GHOST_WindowWin32::adjustWindowRectForClosestMonitor(LPRECT win_rect, + DWORD dwStyle, + DWORD dwExStyle) { - /* Windows can span multiple monitors, but must be usable. The desktop can have a larger - * surface than all monitors combined, for example when two monitors are aligned diagonally. - * Therefore we ensure that all the window's corners are within some monitor's Work area. */ - - POINT pt; - HMONITOR hmonitor; + /* Get Details of the closest monitor. */ + HMONITOR hmonitor = MonitorFromRect(win_rect, MONITOR_DEFAULTTONEAREST); MONITORINFOEX monitor; monitor.cbSize = sizeof(MONITORINFOEX); monitor.dwFlags = 0; - - /* We'll need this value before it is altered for checking later. */ - LONG requested_top = win_rect->top; - - /* Note that with MonitorFromPoint using MONITOR_DEFAULTTONEAREST, it will return - * the exact monitor if there is one at the location or the nearest monitor if not. */ - - /* Top-left. */ - pt.x = win_rect->left; - pt.y = win_rect->top; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); GetMonitorInfo(hmonitor, &monitor); - win_rect->top = max(win_rect->top, monitor.rcWork.top); - win_rect->left = max(win_rect->left, monitor.rcWork.left); - /* Top-right. */ - pt.x = win_rect->right; - pt.y = win_rect->top; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); - win_rect->top = max(win_rect->top, monitor.rcWork.top); - win_rect->right = min(win_rect->right, monitor.rcWork.right); - - /* Bottom-left. */ - pt.x = win_rect->left; - pt.y = win_rect->bottom; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); - win_rect->bottom = min(win_rect->bottom, monitor.rcWork.bottom); - win_rect->left = max(win_rect->left, monitor.rcWork.left); - - /* Bottom-right. */ - pt.x = win_rect->right; - pt.y = win_rect->bottom; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); - win_rect->bottom = min(win_rect->bottom, monitor.rcWork.bottom); - win_rect->right = min(win_rect->right, monitor.rcWork.right); + /* Constrain requested size and position to fit within this monitor. */ + LONG width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect->right - win_rect->left); + LONG height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect->bottom - win_rect->top); + win_rect->left = min(max(monitor.rcWork.left, win_rect->left), monitor.rcWork.right - width); + win_rect->right = win_rect->left + width; + win_rect->top = min(max(monitor.rcWork.top, win_rect->top), monitor.rcWork.bottom - height); + win_rect->bottom = win_rect->top + height; /* With Windows 10 and newer we can adjust for chrome that differs with DPI and scale. */ GHOST_WIN32_AdjustWindowRectExForDpi fpAdjustWindowRectExForDpi = nullptr; @@ -358,9 +327,6 @@ void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyl /* Adjust to allow for caption, borders, shadows, scaling, etc. Resulting values can be * correctly outside of monitor bounds. NOTE: You cannot specify #WS_OVERLAPPED when calling. */ if (fpAdjustWindowRectExForDpi) { - /* Use the DPI of the monitor that is at the middle of the rect. */ - hmonitor = MonitorFromRect(win_rect, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); UINT dpiX, dpiY; GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); fpAdjustWindowRectExForDpi(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle, dpiX); @@ -369,12 +335,7 @@ void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyl AdjustWindowRectEx(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle); } - /* Don't hide the title bar. Check the working area of the monitor at the top-left corner, using - * the original top since the justWindowRects might have altered it to different monitor. */ - pt.x = win_rect->left; - pt.y = requested_top; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); + /* But never allow a top position that can hide part of the title bar. */ win_rect->top = max(monitor.rcWork.top, win_rect->top); } diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index b6c4aa25c79..44071f0915e 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -87,12 +87,12 @@ class GHOST_WindowWin32 : public GHOST_Window { ~GHOST_WindowWin32(); /** - * Adjusts a requested window rect to fit and position within the desktop. + * Adjusts a requested window rect to fit and position correctly in monitor. * \param win_rect: pointer to rectangle that will be modified. * \param dwStyle: The Window Style of the window whose required size is to be calculated. * \param dwExStyle: The Extended Window Style of the window. */ - void adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle); + void adjustWindowRectForClosestMonitor(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle); /** * Returns indication as to whether the window is valid. diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png index eb1250cf5a5..384822af6a5 100644 Binary files a/release/datafiles/splash.png and b/release/datafiles/splash.png differ diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index f9accbe5143..4bad5530e52 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -3513,9 +3513,6 @@ def km_animation_channels(params): ("anim.channels_ungroup", {"type": 'G', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Menus. *_template_items_context_menu("DOPESHEET_MT_channel_context_menu", params.context_menu_event), - # View - ("anim.channel_view_pick", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "alt": True}, None), - ("anim.channels_view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None), ]) return keymap @@ -5634,8 +5631,6 @@ def km_curves(params): ("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("curves.delete", {"type": 'X', "value": 'PRESS'}, None), ("curves.delete", {"type": 'DEL', "value": 'PRESS'}, None), - ("curves.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), - ("curves.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ]) return keymap diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index c837a038c9f..8e09a64b915 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -604,7 +604,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): colliding_names = [] for collection in ( # Built-in names. - {"shade_smooth": None, "crease": None}, + {"shade_smooth": None, "normal": None, "crease": None}, mesh.attributes, None if ob is None else ob.vertex_groups, ): diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index eed77d93de9..af9b9e527e6 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -474,9 +474,6 @@ class DOPESHEET_MT_channel(Menu): layout.separator() layout.operator("anim.channels_fcurves_enable") - layout.separator() - layout.operator("anim.channels_view_selected") - class DOPESHEET_MT_key(Menu): bl_label = "Key" @@ -604,9 +601,6 @@ class DOPESHEET_MT_gpencil_channel(Menu): layout.separator() layout.operator_menu_enum("anim.channels_move", "direction", text="Move...") - layout.separator() - layout.operator("anim.channels_view_selected") - class DOPESHEET_MT_gpencil_key(Menu): bl_label = "Key" @@ -695,9 +689,6 @@ class DOPESHEET_MT_channel_context_menu(Menu): # This menu is used from the graph editor too. is_graph_editor = context.area.type == 'GRAPH_EDITOR' - layout.separator() - layout.operator("anim.channels_view_selected") - layout.operator("anim.channels_setting_enable", text="Mute Channels").type = 'MUTE' layout.operator("anim.channels_setting_disable", text="Unmute Channels").type = 'MUTE' layout.separator() diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 5a84bd5140d..5a550acd107 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -239,9 +239,6 @@ class GRAPH_MT_channel(Menu): layout.separator() layout.operator("anim.channels_fcurves_enable") - layout.separator() - layout.operator("anim.channels_view_selected") - class GRAPH_MT_key(Menu): bl_label = "Key" diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index b63a84cfc81..c54dea94318 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -574,11 +574,6 @@ class NODE_MT_context_menu(Menu): layout.menu("NODE_MT_context_menu_select_menu") layout.menu("NODE_MT_context_menu_show_hide_menu") - if active_node: - layout.separator() - props = layout.operator("wm.doc_view_manual", text="Online Manual", icon='URL') - props.doc_id = active_node.bl_idname - class NODE_PT_active_node_generic(Panel): bl_space_type = 'NODE_EDITOR' diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e2335af687d..28180be1698 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2044,16 +2044,6 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu): layout.operator("paint.vert_select_linked", text="Select Linked") -class VIEW3D_MT_edit_curves_select_more_less(Menu): - bl_label = "Select More/Less" - - def draw(self, _context): - layout = self.layout - - layout.operator("curves.select_more", text="More") - layout.operator("curves.select_less", text="Less") - - class VIEW3D_MT_select_edit_curves(Menu): bl_label = "Select" @@ -2063,17 +2053,10 @@ class VIEW3D_MT_select_edit_curves(Menu): layout.operator("curves.select_all", text="All").action = 'SELECT' layout.operator("curves.select_all", text="None").action = 'DESELECT' layout.operator("curves.select_all", text="Invert").action = 'INVERT' - - layout.separator() - layout.operator("curves.select_random", text="Random") layout.operator("curves.select_end", text="Endpoints") layout.operator("curves.select_linked", text="Linked") - layout.separator() - - layout.menu("VIEW3D_MT_edit_curves_select_more_less") - class VIEW3D_MT_select_sculpt_curves(Menu): bl_label = "Select" @@ -8063,7 +8046,6 @@ classes = ( VIEW3D_MT_select_gpencil, VIEW3D_MT_select_paint_mask, VIEW3D_MT_select_paint_mask_vertex, - VIEW3D_MT_edit_curves_select_more_less, VIEW3D_MT_select_edit_curves, VIEW3D_MT_select_sculpt_curves, VIEW3D_MT_mesh_add, diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 76558b9ba28..7c01a9205fc 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -41,7 +41,6 @@ typedef enum eAttrDomainMask { ATTR_DOMAIN_MASK_CURVE = (1 << 4), ATTR_DOMAIN_MASK_ALL = (1 << 5) - 1 } eAttrDomainMask; -ENUM_OPERATORS(eAttrDomainMask, ATTR_DOMAIN_MASK_ALL); #define ATTR_DOMAIN_AS_MASK(domain) ((eAttrDomainMask)((1 << (int)(domain)))) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 72b89dd634c..26f45b79aef 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -17,15 +17,17 @@ extern "C" { */ /* Blender major and minor version. */ -#define BLENDER_VERSION 306 +#define BLENDER_VERSION 305 /* Blender patch version for bugfix releases. */ #define BLENDER_VERSION_PATCH 0 /** Blender release cycle stage: alpha/beta/rc/release. */ -#define BLENDER_VERSION_CYCLE alpha +#define BLENDER_VERSION_CYCLE beta + +/* TODO proper version bump. */ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 0 +#define BLENDER_FILE_SUBVERSION 10 /* 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_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index ba13d9d6a6c..67b282ff2ad 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -108,7 +108,7 @@ BVHTree *bvhtree_from_editmesh_verts( */ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, struct BMEditMesh *em, - blender::BitSpan mask, + const blender::BitVector<> &mask, int verts_num_active, float epsilon, int tree_type, @@ -124,7 +124,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, BVHTree *bvhtree_from_mesh_verts_ex(struct BVHTreeFromMesh *data, const float (*vert_positions)[3], int verts_num, - blender::BitSpan verts_mask, + const blender::BitVector<> &verts_mask, int verts_num_active, float epsilon, int tree_type, @@ -138,7 +138,7 @@ BVHTree *bvhtree_from_editmesh_edges( */ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, struct BMEditMesh *em, - blender::BitSpan edges_mask, + const blender::BitVector<> &edges_mask, int edges_num_active, float epsilon, int tree_type, @@ -156,7 +156,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(struct BVHTreeFromMesh *data, const float (*vert_positions)[3], const struct MEdge *edge, int edges_num, - blender::BitSpan edges_mask, + const blender::BitVector<> &edges_mask, int edges_num_active, float epsilon, int tree_type, @@ -170,7 +170,7 @@ BVHTree *bvhtree_from_editmesh_looptri( */ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, struct BMEditMesh *em, - blender::BitSpan mask, + const blender::BitVector<> &mask, int looptri_num_active, float epsilon, int tree_type, @@ -184,7 +184,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data, const struct MLoop *mloop, const struct MLoopTri *looptri, int looptri_num, - blender::BitSpan mask, + const blender::BitVector<> &mask, int looptri_num_active, float epsilon, int tree_type, diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 297cd3c2433..9cddc39f43c 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -282,7 +282,6 @@ bool CustomData_has_layer(const struct CustomData *data, int type); * Returns the number of layers with this type. */ int CustomData_number_of_layers(const struct CustomData *data, int type); -int CustomData_number_of_anonymous_layers(const struct CustomData *data, int type); int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask); /** diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 69cf1f1edf6..62b80a627bb 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -373,8 +373,6 @@ bool BKE_fcurve_calc_range( /** * Calculate the extents of F-Curve's data. - * \param range Only calculate the bounds of the FCurve in the given range. - * Does the full range if NULL. */ bool BKE_fcurve_calc_bounds(const struct FCurve *fcu, float *xmin, @@ -382,8 +380,7 @@ bool BKE_fcurve_calc_bounds(const struct FCurve *fcu, float *ymin, float *ymax, bool do_sel_only, - bool include_handles, - const float range[2]); + bool include_handles); /** * Return an array of keyed frames, rounded to `interval`. diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index a58b4166ba5..0fa3d16d328 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -41,10 +41,10 @@ struct PropertyRNA; */ void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user); /** - * Remove & Frees all NLA strips from the given NLA track, - * then frees (doesn't remove) the track itself. + * Remove the given NLA track from the set of NLA tracks, free the track's data, + * and the track itself. */ -void BKE_nlatrack_free(struct NlaTrack *nlt, bool do_id_user); +void BKE_nlatrack_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user); /** * Free the elements of type NLA Tracks provided in the given list, but do not free * the list itself since that is not free-standing @@ -95,17 +95,6 @@ struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt, struct NlaTrack *prev, bool is_liboverride); -/** - * Removes the given NLA track from the list of tracks provided. - */ -void BKE_nlatrack_remove(ListBase *tracks, struct NlaTrack *nlt); - -/** - * Remove the given NLA track from the list of NLA tracks, free the track's data, - * and the track itself. - */ -void BKE_nlatrack_remove_and_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user); - /** * Create a NLA Strip referencing the given Action. */ diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 2ba03b6d1cf..8a6e1486701 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -316,6 +316,9 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const { + if (writable_ != Writable) { + return {}; + } CustomData *custom_data = custom_data_access_.get_custom_data(owner); if (custom_data == nullptr) { return {}; diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index a1a74e3b81c..b429756e754 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -37,6 +37,10 @@ class BuiltinAttributeProvider { Creatable, NonCreatable, }; + enum WritableEnum { + Writable, + Readonly, + }; enum DeletableEnum { Deletable, NonDeletable, @@ -47,6 +51,7 @@ class BuiltinAttributeProvider { const eAttrDomain domain_; const eCustomDataType data_type_; const CreatableEnum createable_; + const WritableEnum writable_; const DeletableEnum deletable_; const AttributeValidator validator_; @@ -55,12 +60,14 @@ class BuiltinAttributeProvider { const eAttrDomain domain, const eCustomDataType data_type, const CreatableEnum createable, + const WritableEnum writable, const DeletableEnum deletable, AttributeValidator validator = {}) : name_(std::move(name)), domain_(domain), data_type_(data_type), createable_(createable), + writable_(writable), deletable_(deletable), validator_(validator) { @@ -198,14 +205,20 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { const eCustomDataType attribute_type, const eCustomDataType stored_type, const CreatableEnum creatable, + const WritableEnum writable, const DeletableEnum deletable, const CustomDataAccessInfo custom_data_access, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute, const UpdateOnChange update_on_write, const AttributeValidator validator = {}) - : BuiltinAttributeProvider( - std::move(attribute_name), domain, attribute_type, creatable, deletable, validator), + : BuiltinAttributeProvider(std::move(attribute_name), + domain, + attribute_type, + creatable, + writable, + deletable, + validator), stored_type_(stored_type), custom_data_access_(custom_data_access), as_read_attribute_(as_read_attribute), diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index f29407b641b..fc1072d4cb8 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -29,7 +29,6 @@ #include "MEM_guardedalloc.h" -using blender::BitSpan; using blender::BitVector; using blender::float3; using blender::IndexRange; @@ -673,7 +672,7 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon, int tree_type, int axis, BMEditMesh *em, - const BitSpan verts_mask, + const BitVector<> &verts_mask, int verts_num_active) { BM_mesh_elem_table_ensure(em->bm, BM_VERT); @@ -707,7 +706,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon, int axis, const float (*positions)[3], const int verts_num, - const BitSpan verts_mask, + const BitVector<> &verts_mask, int verts_num_active) { if (!verts_mask.is_empty()) { @@ -738,7 +737,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon, BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, BMEditMesh *em, - const BitSpan verts_mask, + const BitVector<> &verts_mask, int verts_num_active, float epsilon, int tree_type, @@ -765,7 +764,7 @@ BVHTree *bvhtree_from_editmesh_verts( BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, const float (*vert_positions)[3], const int verts_num, - const BitSpan verts_mask, + const BitVector<> &verts_mask, int verts_num_active, float epsilon, int tree_type, @@ -795,7 +794,7 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon, int tree_type, int axis, BMEditMesh *em, - const BitSpan edges_mask, + const BitVector<> &edges_mask, int edges_num_active) { BM_mesh_elem_table_ensure(em->bm, BM_EDGE); @@ -834,7 +833,7 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon, static BVHTree *bvhtree_from_mesh_edges_create_tree(const float (*positions)[3], const MEdge *edge, const int edge_num, - const BitSpan edges_mask, + const BitVector<> &edges_mask, int edges_num_active, float epsilon, int tree_type, @@ -872,7 +871,7 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const float (*positions)[3], BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, BMEditMesh *em, - const BitSpan edges_mask, + const BitVector<> &edges_mask, int edges_num_active, float epsilon, int tree_type, @@ -900,7 +899,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data, const float (*vert_positions)[3], const MEdge *edge, const int edges_num, - const BitSpan edges_mask, + const BitVector<> &edges_mask, int edges_num_active, float epsilon, int tree_type, @@ -932,7 +931,7 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon, const float (*positions)[3], const MFace *face, const int faces_num, - const BitSpan faces_mask, + const BitVector<> &faces_mask, int faces_num_active) { if (faces_num == 0) { @@ -985,7 +984,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon, int tree_type, int axis, BMEditMesh *em, - const BitSpan looptri_mask, + const BitVector<> &looptri_mask, int looptri_num_active) { const int looptri_num = em->tottri; @@ -1039,7 +1038,7 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, const MLoop *mloop, const MLoopTri *looptri, const int looptri_num, - const BitSpan looptri_mask, + const BitVector<> &looptri_mask, int looptri_num_active) { if (!looptri_mask.is_empty()) { @@ -1080,7 +1079,7 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, BMEditMesh *em, - const BitSpan looptri_mask, + const BitVector<> &looptri_mask, int looptri_num_active, float epsilon, int tree_type, @@ -1110,7 +1109,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, const struct MLoop *mloop, const struct MLoopTri *looptri, const int looptri_num, - const BitSpan looptri_mask, + const BitVector<> &looptri_mask, int looptri_num_active, float epsilon, int tree_type, diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index eac61c6c5c3..75a8c865170 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2991,19 +2991,6 @@ int CustomData_number_of_layers(const CustomData *data, const int type) return number; } -int CustomData_number_of_anonymous_layers(const CustomData *data, const int type) -{ - int number = 0; - - for (int i = 0; i < data->totlayer; i++) { - if (data->layers[i].type == type && data->layers[i].anonymous_id != nullptr) { - number++; - } - } - - return number; -} - int CustomData_number_of_layers_typemask(const CustomData *data, const eCustomDataMask mask) { int number = 0; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 8e054d4d35f..304ac5c63a0 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -557,11 +557,10 @@ int BKE_fcurve_bezt_binarysearch_index(const BezTriple array[], /* ...................................... */ /* Helper for calc_fcurve_* functions -> find first and last BezTriple to be used. */ -static bool get_fcurve_end_keyframes(const FCurve *fcu, - BezTriple **first, - BezTriple **last, - const bool do_sel_only, - const float range[2]) +static short get_fcurve_end_keyframes(const FCurve *fcu, + BezTriple **first, + BezTriple **last, + const bool do_sel_only) { bool found = false; @@ -574,31 +573,11 @@ static bool get_fcurve_end_keyframes(const FCurve *fcu, return found; } - int first_index = 0; - int last_index = fcu->totvert - 1; - - if (range != NULL) { - /* If a range is passed in find the first and last keyframe within that range. */ - bool replace = false; - first_index = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, range[0], fcu->totvert, &replace); - last_index = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, range[1], fcu->totvert, &replace); - - /* If first and last index are the same, no keyframes were found in the range. */ - if (first_index == last_index) { - return found; - } - - /* The binary search returns an index where a keyframe would be inserted, - so it needs to be clamped to ensure it is in range of the array. */ - first_index = clamp_i(first_index, 0, fcu->totvert - 1); - last_index = clamp_i(last_index - 1, 0, fcu->totvert - 1); - } - /* Only include selected items? */ if (do_sel_only) { /* Find first selected. */ - for (int i = first_index; i <= last_index; i++) { - BezTriple *bezt = &fcu->bezt[i]; + BezTriple *bezt = fcu->bezt; + for (int i = 0; i < fcu->totvert; bezt++, i++) { if (BEZT_ISSEL_ANY(bezt)) { *first = bezt; found = true; @@ -607,8 +586,8 @@ static bool get_fcurve_end_keyframes(const FCurve *fcu, } /* Find last selected. */ - for (int i = last_index; i >= first_index; i--) { - BezTriple *bezt = &fcu->bezt[i]; + bezt = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, fcu->totvert); + for (int i = 0; i < fcu->totvert; bezt--, i++) { if (BEZT_ISSEL_ANY(bezt)) { *last = bezt; found = true; @@ -617,8 +596,9 @@ static bool get_fcurve_end_keyframes(const FCurve *fcu, } } else { - *first = &fcu->bezt[first_index]; - *last = &fcu->bezt[last_index]; + /* Use the whole array. */ + *first = fcu->bezt; + *last = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, fcu->totvert); found = true; } @@ -631,25 +611,23 @@ bool BKE_fcurve_calc_bounds(const FCurve *fcu, float *ymin, float *ymax, const bool do_sel_only, - const bool include_handles, - const float range[2]) + const bool include_handles) { float xminv = 999999999.0f, xmaxv = -999999999.0f; float yminv = 999999999.0f, ymaxv = -999999999.0f; bool foundvert = false; - const bool use_range = range != NULL; - if (fcu->totvert) { if (fcu->bezt) { + BezTriple *bezt_first = NULL, *bezt_last = NULL; if (xmin || xmax) { - BezTriple *bezt_first = NULL, *bezt_last = NULL; - foundvert = get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only, range); + /* Get endpoint keyframes. */ + foundvert = get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only); if (bezt_first) { BLI_assert(bezt_last != NULL); - foundvert = true; + if (include_handles) { xminv = min_fff(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]); xmaxv = max_fff(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]); @@ -667,9 +645,6 @@ bool BKE_fcurve_calc_bounds(const FCurve *fcu, int i; for (bezt = fcu->bezt, i = 0; i < fcu->totvert; prevbezt = bezt, bezt++, i++) { - if (use_range && (bezt->vec[1][0] < range[0] || bezt->vec[1][0] > range[1])) { - continue; - } if ((do_sel_only == false) || BEZT_ISSEL_ANY(bezt)) { /* Keyframe itself. */ yminv = min_ff(yminv, bezt->vec[1][1]); @@ -742,10 +717,10 @@ bool BKE_fcurve_calc_bounds(const FCurve *fcu, } if (xmin) { - *xmin = use_range ? range[0] : 0.0f; + *xmin = 0.0f; } if (xmax) { - *xmax = use_range ? range[1] : 1.0f; + *xmax = 1.0f; } if (ymin) { @@ -770,7 +745,7 @@ bool BKE_fcurve_calc_range( BezTriple *bezt_first = NULL, *bezt_last = NULL; /* Get endpoint keyframes. */ - get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only, NULL); + get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only); if (bezt_first) { BLI_assert(bezt_last != NULL); diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 7401546c19d..e775a2a00a9 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -375,6 +375,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_FLOAT3, CD_PROP_FLOAT3, BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::NonDeletable, point_access, make_array_read_attribute, @@ -386,6 +387,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_FLOAT, CD_PROP_FLOAT, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -397,6 +399,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT32, CD_PROP_INT32, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -408,6 +411,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_FLOAT, CD_PROP_FLOAT, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -419,6 +423,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_FLOAT3, CD_PROP_FLOAT3, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -430,6 +435,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_FLOAT3, CD_PROP_FLOAT3, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -447,6 +453,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT8, CD_PROP_INT8, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -459,6 +466,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT8, CD_PROP_INT8, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -471,6 +479,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_FLOAT, CD_PROP_FLOAT, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -486,6 +495,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT8, CD_PROP_INT8, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, curve_access, make_array_read_attribute, @@ -504,6 +514,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT8, CD_PROP_INT8, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, curve_access, make_array_read_attribute, @@ -522,6 +533,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT8, CD_PROP_INT8, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, curve_access, make_array_read_attribute, @@ -540,6 +552,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT8, CD_PROP_INT8, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, curve_access, make_array_read_attribute, @@ -556,6 +569,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_INT32, CD_PROP_INT32, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, curve_access, make_array_read_attribute, @@ -568,6 +582,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() CD_PROP_BOOL, CD_PROP_BOOL, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, curve_access, make_array_read_attribute, diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc index 0c8c6620668..25143bf20a0 100644 --- a/source/blender/blenkernel/intern/geometry_component_instances.cc +++ b/source/blender/blenkernel/intern/geometry_component_instances.cc @@ -129,7 +129,7 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider public: InstancePositionAttributeProvider() : BuiltinAttributeProvider( - "position", ATTR_DOMAIN_INSTANCE, CD_PROP_FLOAT3, NonCreatable, NonDeletable) + "position", ATTR_DOMAIN_INSTANCE, CD_PROP_FLOAT3, NonCreatable, Writable, NonDeletable) { } @@ -200,6 +200,7 @@ static ComponentAttributeProviders create_attribute_providers_for_instances() CD_PROP_INT32, CD_PROP_INT32, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, instance_custom_data_access, make_array_read_attribute, diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 44697ca2a30..bdb1b0edf8b 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1137,6 +1137,48 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { } }; +/** + * This provider makes face normals available as a read-only float3 attribute. + */ +class NormalAttributeProvider final : public BuiltinAttributeProvider { + public: + NormalAttributeProvider() + : BuiltinAttributeProvider( + "normal", ATTR_DOMAIN_FACE, CD_PROP_FLOAT3, NonCreatable, Readonly, NonDeletable) + { + } + + GVArray try_get_for_read(const void *owner) const final + { + const Mesh *mesh = static_cast(owner); + if (mesh == nullptr || mesh->totpoly == 0) { + return {}; + } + return VArray::ForSpan({(float3 *)BKE_mesh_poly_normals_ensure(mesh), mesh->totpoly}); + } + + GAttributeWriter try_get_for_write(void * /*owner*/) const final + { + return {}; + } + + bool try_delete(void * /*owner*/) const final + { + return false; + } + + bool try_create(void * /*owner*/, const AttributeInit & /*initializer*/) const final + { + return false; + } + + bool exists(const void *owner) const final + { + const Mesh *mesh = static_cast(owner); + return mesh->totpoly != 0; + } +}; + /** * In this function all the attribute providers for a mesh component are created. Most data in this * function is statically allocated, because it does not change over time. @@ -1180,17 +1222,21 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() CD_PROP_FLOAT3, CD_PROP_FLOAT3, BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::NonDeletable, point_access, make_array_read_attribute, make_array_write_attribute, tag_component_positions_changed); + static NormalAttributeProvider normal; + static BuiltinCustomDataLayerProvider id("id", ATTR_DOMAIN_POINT, CD_PROP_INT32, CD_PROP_INT32, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -1209,6 +1255,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() CD_PROP_INT32, CD_PROP_INT32, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, face_access, make_array_read_attribute, @@ -1222,6 +1269,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() CD_PROP_BOOL, CD_MPOLY, BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::NonDeletable, face_access, make_derived_read_attribute, @@ -1233,6 +1281,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() CD_PROP_BOOL, CD_PROP_BOOL, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, edge_access, make_array_read_attribute, @@ -1245,6 +1294,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() CD_PROP_FLOAT, CD_CREASE, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, edge_access, make_array_read_attribute, @@ -1258,7 +1308,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() static CustomDataAttributeProvider face_custom_data(ATTR_DOMAIN_FACE, face_access); return ComponentAttributeProviders( - {&position, &id, &material_index, &shade_smooth, &sharp_edge, &crease}, + {&position, &id, &material_index, &shade_smooth, &sharp_edge, &normal, &crease}, {&corner_custom_data, &vertex_groups, &point_custom_data, diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc index 41966fe868a..71484bbd5f0 100644 --- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc +++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc @@ -142,6 +142,7 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() CD_PROP_FLOAT3, CD_PROP_FLOAT3, BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::NonDeletable, point_access, make_array_read_attribute, @@ -152,6 +153,7 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() CD_PROP_FLOAT, CD_PROP_FLOAT, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, @@ -162,6 +164,7 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() CD_PROP_INT32, CD_PROP_INT32, BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, BuiltinAttributeProvider::Deletable, point_access, make_array_read_attribute, diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index 662a33b44be..8115920f938 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -190,9 +190,6 @@ static int stroke_march_next_point(const bGPDstroke *gps, float *pressure, float *strength, float *vert_color, - float *uv_fac, - float *uv_fill, - float *uv_rot, float *ratio_result, int *index_from, int *index_to) @@ -274,10 +271,6 @@ static int stroke_march_next_point(const bGPDstroke *gps, gps->points[next_point_index].pressure, gps->points[*index_from].pressure, vratio); *strength = interpf( gps->points[next_point_index].strength, gps->points[*index_from].strength, vratio); - *uv_fac = interpf(gps->points[next_point_index].uv_fac, gps->points[*index_from].uv_fac, vratio); - *uv_rot = interpf(gps->points[next_point_index].uv_rot, gps->points[*index_from].uv_rot, vratio); - interp_v2_v2v2( - uv_fill, gps->points[*index_from].uv_fill, gps->points[next_point_index].uv_fill, vratio); interp_v4_v4v4(vert_color, gps->points[*index_from].vert_color, gps->points[next_point_index].vert_color, @@ -481,7 +474,6 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, int next_point_index = 1; int i = 0; float pressure, strength, ratio_result; - float uv_fac, uv_rot, uv_fill[2]; float vert_color[4]; int index_from, index_to; float last_coord[3]; @@ -512,9 +504,6 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, &pressure, &strength, vert_color, - &uv_fac, - uv_fill, - &uv_rot, &ratio_result, &index_from, &index_to)) > -1) { @@ -525,10 +514,6 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, copy_v3_v3(&pt2->x, last_coord); new_pt[i].pressure = pressure; new_pt[i].strength = strength; - new_pt[i].uv_fac = uv_fac; - new_pt[i].uv_rot = uv_rot; - copy_v2_v2(new_pt[i].uv_fill, uv_fill); - memcpy(new_pt[i].vert_color, vert_color, sizeof(float[4])); if (select) { new_pt[i].flag |= GP_SPOINT_SELECT; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index f1f6a9a97bc..5b4c4edd0a2 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -17,6 +17,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "BLI_bit_vector.hh" #include "BLI_bounds.hh" #include "BLI_edgehash.h" #include "BLI_endian_switch.h" @@ -65,6 +66,7 @@ #include "BLO_read_write.h" +using blender::BitVector; using blender::float3; using blender::MutableSpan; using blender::Span; diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index 159ff94d24d..45ad8f2b626 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -316,7 +316,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( BKE_mesh_vertex_normals_ensure(mesh) : nullptr; const int *index = static_cast(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX)); - const blender::BitSpan facedot_tags = mesh->runtime->subsurf_face_dot_tags; + const blender::BitVector<> &facedot_tags = mesh->runtime->subsurf_face_dot_tags; if (index) { for (int i = 0; i < mesh->totpoly; i++, mp++) { diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index a3e34224a02..c83de7a843a 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -42,7 +42,6 @@ using blender::BitVector; using blender::float3; using blender::int2; -using blender::MutableBitSpan; using blender::MutableSpan; using blender::short2; using blender::Span; @@ -1239,7 +1238,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop const Span edge_to_loops, const Span loop_to_poly, const int *e2l_prev, - MutableBitSpan skip_loops, + BitVector<> &skip_loops, const int ml_curr_index, const int ml_prev_index, const int mp_curr_index) diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 2dbab08ef20..29d4cc802fe 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -91,7 +91,7 @@ void BKE_nlastrip_free(NlaStrip *strip, const bool do_id_user) MEM_freeN(strip); } -void BKE_nlatrack_free(NlaTrack *nlt, const bool do_id_user) +void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user) { NlaStrip *strip, *stripn; @@ -107,7 +107,12 @@ void BKE_nlatrack_free(NlaTrack *nlt, const bool do_id_user) } /* free NLA track itself now */ - MEM_freeN(nlt); + if (tracks) { + BLI_freelinkN(tracks, nlt); + } + else { + MEM_freeN(nlt); + } } void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user) @@ -122,7 +127,7 @@ void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user) /* free tracks one by one */ for (nlt = tracks->first; nlt; nlt = nltn) { nltn = nlt->next; - BKE_nlatrack_remove_and_free(tracks, nlt, do_id_user); + BKE_nlatrack_free(tracks, nlt, do_id_user); } /* clear the list's pointers to be safe */ @@ -509,20 +514,6 @@ void BKE_nla_strip_foreach_id(NlaStrip *strip, LibraryForeachIDData *data) } } -/* Removing ------------------------------------------ */ - -void BKE_nlatrack_remove(ListBase *tracks, struct NlaTrack *nlt) -{ - BLI_assert(tracks); - BLI_remlink(tracks, nlt); -} - -void BKE_nlatrack_remove_and_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user) -{ - BKE_nlatrack_remove(tracks, nlt); - BKE_nlatrack_free(nlt, do_id_user); -} - /* *************************************************** */ /* NLA Evaluation <-> Editing Stuff */ diff --git a/source/blender/blenkernel/intern/nla_test.cc b/source/blender/blenkernel/intern/nla_test.cc index 0520a3b270e..414391a208f 100644 --- a/source/blender/blenkernel/intern/nla_test.cc +++ b/source/blender/blenkernel/intern/nla_test.cc @@ -77,43 +77,18 @@ TEST(nla_track, BKE_nlatrack_remove_strip) strip2.start = 11; strip2.end = 20; - /* Add NLA strips to the NLATrack. */ + // 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. */ + // 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. */ + // ensure the correct strip was removed. EXPECT_EQ(-1, BLI_findindex(&track.strips, &strip2)); } -TEST(nla_track, BKE_nlatrack_remove_and_free) -{ - AnimData adt{}; - NlaTrack *track1; - NlaTrack *track2; - - /* Add NLA tracks to the Animation Data. */ - track1 = BKE_nlatrack_add(&adt, NULL, false); - track2 = BKE_nlatrack_add(&adt, track1, false); - - /* Ensure we have 2 tracks in the track. */ - EXPECT_EQ(2, BLI_listbase_count(&adt.nla_tracks)); - - BKE_nlatrack_remove_and_free(&adt.nla_tracks, track2, false); - EXPECT_EQ(1, BLI_listbase_count(&adt.nla_tracks)); - - /* Ensure the correct track was removed. */ - EXPECT_EQ(-1, BLI_findindex(&adt.nla_tracks, track2)); - - /* Free the rest of the tracks, and ensure they are removed. */ - BKE_nlatrack_remove_and_free(&adt.nla_tracks, track1, false); - EXPECT_EQ(0, BLI_listbase_count(&adt.nla_tracks)); - EXPECT_EQ(-1, BLI_findindex(&adt.nla_tracks, track1)); -} - } // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 5c66af4dd81..3ec6525ac6b 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -2266,8 +2266,6 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob) return pbvh; } - ob->sculpt->islands_valid = false; - if (ob->sculpt->bm != nullptr) { /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH. */ pbvh = build_pbvh_for_dynamic_topology(ob); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 0f3eccb5bd0..95ef6b7b925 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -956,9 +956,7 @@ ScrArea *BKE_screen_area_map_find_area_xy(const ScrAreaMap *areamap, const int xy[2]) { LISTBASE_FOREACH (ScrArea *, area, &areamap->areabase) { - /* Test area's outer screen verts, not inner `area->totrct`. */ - if (xy[0] >= area->v1->vec.x && xy[0] <= area->v4->vec.x && xy[1] >= area->v1->vec.y && - xy[1] <= area->v2->vec.y) { + if (BLI_rcti_isect_pt_v(&area->totrct, xy)) { if (ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) { return area; } diff --git a/source/blender/blenlib/BLI_bit_ref.hh b/source/blender/blenlib/BLI_bit_ref.hh deleted file mode 100644 index 09f17a0bb93..00000000000 --- a/source/blender/blenlib/BLI_bit_ref.hh +++ /dev/null @@ -1,234 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup bli - * - * This file provides the basis for processing "indexed bits" (i.e. every bit has an index). - * The main purpose of this file is to define how bits are indexed within a memory buffer. - * For example, one has to define whether the first bit is the least or most significant bit and - * how endianness affect the bit order. - * - * The order is defined as follows: - * - Every indexed bit is part of an #BitInt. These ints are ordered by their address as usual. - * - Within each #BitInt, the bits are ordered from least to most significant. - */ - -#include "BLI_index_range.hh" -#include "BLI_utildefines.h" - -#include - -namespace blender::bits { - -/** Using a large integer type is better because then it's easier to process many bits at once. */ -using BitInt = uint64_t; -/** Number of bits that fit into #BitInt. */ -static constexpr int64_t BitsPerInt = int64_t(sizeof(BitInt) * 8); -/** Shift amount to get from a bit index to an int index. Equivalent to `log(BitsPerInt, 2)`. */ -static constexpr int64_t BitToIntIndexShift = 3 + (sizeof(BitInt) >= 2) + (sizeof(BitInt) >= 4) + - (sizeof(BitInt) >= 8); -/** Bit mask containing a 1 for the last few bits that index a bit inside of an #BitInt. */ -static constexpr BitInt BitIndexMask = (BitInt(1) << BitToIntIndexShift) - 1; - -inline BitInt mask_first_n_bits(const int64_t n) -{ - BLI_assert(n >= 0); - BLI_assert(n <= BitsPerInt); - if (n == BitsPerInt) { - return BitInt(-1); - } - return (BitInt(1) << n) - 1; -} - -inline BitInt mask_last_n_bits(const int64_t n) -{ - return ~mask_first_n_bits(BitsPerInt - n); -} - -inline BitInt mask_range_bits(const int64_t start, const int64_t size) -{ - BLI_assert(start >= 0); - BLI_assert(size >= 0); - const int64_t end = start + size; - BLI_assert(end <= BitsPerInt); - if (end == BitsPerInt) { - return mask_last_n_bits(size); - } - return ((BitInt(1) << end) - 1) & ~((BitInt(1) << start) - 1); -} - -inline BitInt mask_single_bit(const int64_t bit_index) -{ - BLI_assert(bit_index >= 0); - BLI_assert(bit_index < BitsPerInt); - return BitInt(1) << bit_index; -} - -inline BitInt *int_containing_bit(BitInt *data, const int64_t bit_index) -{ - return data + (bit_index >> BitToIntIndexShift); -} - -inline const BitInt *int_containing_bit(const BitInt *data, const int64_t bit_index) -{ - return data + (bit_index >> BitToIntIndexShift); -} - -/** - * 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 integer that the bit is in. */ - const BitInt *int_; - /** All zeros except for a single one at the bit that is referenced. */ - BitInt mask_; - - friend class MutableBitRef; - - public: - BitRef() = default; - - /** - * Reference a specific bit in an array. Note that #data does *not* have to point to the - * exact integer the bit is in. - */ - BitRef(const BitInt *data, const int64_t bit_index) - { - int_ = int_containing_bit(data, bit_index); - mask_ = mask_single_bit(bit_index & BitIndexMask); - } - - /** - * Return true when the bit is currently 1 and false otherwise. - */ - bool test() const - { - const BitInt value = *int_; - const BitInt masked_value = value & mask_; - return masked_value != 0; - } - - operator bool() const - { - return this->test(); - } -}; - -/** - * Similar to #BitRef, but also allows changing the referenced bit. - */ -class MutableBitRef { - private: - /** Points to the integer that the bit is in. */ - BitInt *int_; - /** All zeros except for a single one at the bit that is referenced. */ - BitInt mask_; - - public: - MutableBitRef() = default; - - /** - * Reference a specific bit in an array. Note that #data does *not* have to point to the - * exact int the bit is in. - */ - MutableBitRef(BitInt *data, const int64_t bit_index) - { - int_ = int_containing_bit(data, bit_index); - mask_ = mask_single_bit(bit_index & BitIndexMask); - } - - /** - * Support implicitly casting to a read-only #BitRef. - */ - operator BitRef() const - { - BitRef bit_ref; - bit_ref.int_ = int_; - bit_ref.mask_ = mask_; - return bit_ref; - } - - /** - * Return true when the bit is currently 1 and false otherwise. - */ - bool test() const - { - const BitInt value = *int_; - const BitInt masked_value = value & mask_; - return masked_value != 0; - } - - operator bool() const - { - return this->test(); - } - - /** - * Change the bit to a 1. - */ - void set() - { - *int_ |= mask_; - } - - /** - * Change the bit to a 0. - */ - void reset() - { - *int_ &= ~mask_; - } - - /** - * Change the bit to a 1 if #value is true and 0 otherwise. If the value is highly unpredictable - * by the CPU branch predictor, it can be faster to use #set_branchless instead. - */ - void set(const bool value) - { - if (value) { - this->set(); - } - else { - this->reset(); - } - } - - /** - * Does the same as #set, but does not use a branch. This is faster when the input value is - * unpredictable for the CPU branch predictor (best case for this function is a uniform random - * distribution with 50% probability for true and false). If the value is predictable, this is - * likely slower than #set. - */ - void set_branchless(const bool value) - { - const BitInt value_int = BitInt(value); - BLI_assert(ELEM(value_int, 0, 1)); - const BitInt old = *int_; - *int_ = - /* Unset bit. */ - (~mask_ & old) - /* Optionally set it again. The -1 turns a 1 into `0x00...` and a 0 into `0xff...`. */ - | (mask_ & ~(value_int - 1)); - } -}; - -inline std::ostream &operator<<(std::ostream &stream, const BitRef &bit) -{ - return stream << (bit ? "1" : "0"); -} - -inline std::ostream &operator<<(std::ostream &stream, const MutableBitRef &bit) -{ - return stream << BitRef(bit); -} - -} // namespace blender::bits - -namespace blender { -using bits::BitRef; -using bits::MutableBitRef; -} // namespace blender diff --git a/source/blender/blenlib/BLI_bit_span.hh b/source/blender/blenlib/BLI_bit_span.hh deleted file mode 100644 index 0ab69b7cc67..00000000000 --- a/source/blender/blenlib/BLI_bit_span.hh +++ /dev/null @@ -1,290 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_bit_ref.hh" -#include "BLI_index_range.hh" -#include "BLI_memory_utils.hh" - -namespace blender::bits { - -/** Base class for a const and non-const bit-iterator. */ -class BitIteratorBase { - protected: - const BitInt *data_; - int64_t bit_index_; - - public: - BitIteratorBase(const BitInt *data, const int64_t bit_index) : data_(data), bit_index_(bit_index) - { - } - - BitIteratorBase &operator++() - { - bit_index_++; - return *this; - } - - friend bool operator!=(const BitIteratorBase &a, const BitIteratorBase &b) - { - BLI_assert(a.data_ == b.data_); - return a.bit_index_ != b.bit_index_; - } -}; - -/** Allows iterating over the bits in a memory buffer. */ -class BitIterator : public BitIteratorBase { - public: - BitIterator(const BitInt *data, const int64_t bit_index) : BitIteratorBase(data, bit_index) - { - } - - BitRef operator*() const - { - return BitRef(data_, bit_index_); - } -}; - -/** Allows iterating over the bits in a memory buffer. */ -class MutableBitIterator : public BitIteratorBase { - public: - MutableBitIterator(BitInt *data, const int64_t bit_index) : BitIteratorBase(data, bit_index) - { - } - - MutableBitRef operator*() const - { - return MutableBitRef(const_cast(data_), bit_index_); - } -}; - -/** - * Similar to #Span, but references a range of bits instead of normal C++ types (which must be at - * least one byte large). Use #MutableBitSpan if the values are supposed to be modified. - * - * The beginning and end of a #BitSpan does *not* have to be at byte/int boundaries. It can start - * and end at any bit. - */ -class BitSpan { - private: - /** Base pointer to the integers containing the bits. The actual bit span might start at a much - * higher address when `bit_range_.start()` is large. */ - const BitInt *data_ = nullptr; - /** The range of referenced bits. */ - IndexRange bit_range_ = {0, 0}; - - public: - /** Construct an empty span. */ - BitSpan() = default; - - BitSpan(const BitInt *data, const int64_t size_in_bits) : data_(data), bit_range_(size_in_bits) - { - } - - BitSpan(const BitInt *data, const IndexRange bit_range) : data_(data), bit_range_(bit_range) - { - } - - /** Number of bits referenced by the span. */ - int64_t size() const - { - return bit_range_.size(); - } - - bool is_empty() const - { - return bit_range_.is_empty(); - } - - IndexRange index_range() const - { - return IndexRange(bit_range_.size()); - } - - BitRef operator[](const int64_t index) const - { - BLI_assert(index >= 0); - BLI_assert(index < bit_range_.size()); - return {data_, bit_range_.start() + index}; - } - - BitSpan slice(const IndexRange range) const - { - return {data_, bit_range_.slice(range)}; - } - - const BitInt *data() const - { - return data_; - } - - const IndexRange &bit_range() const - { - return bit_range_; - } - - BitIterator begin() const - { - return {data_, bit_range_.start()}; - } - - BitIterator end() const - { - return {data_, bit_range_.one_after_last()}; - } -}; - -/** Same as #BitSpan, but also allows modifying the referenced bits. */ -class MutableBitSpan { - private: - BitInt *data_ = nullptr; - IndexRange bit_range_ = {0, 0}; - - public: - MutableBitSpan() = default; - - MutableBitSpan(BitInt *data, const int64_t size) : data_(data), bit_range_(size) - { - } - - MutableBitSpan(BitInt *data, const IndexRange bit_range) : data_(data), bit_range_(bit_range) - { - } - - int64_t size() const - { - return bit_range_.size(); - } - - bool is_empty() const - { - return bit_range_.is_empty(); - } - - IndexRange index_range() const - { - return IndexRange(bit_range_.size()); - } - - MutableBitRef operator[](const int64_t index) const - { - BLI_assert(index >= 0); - BLI_assert(index < bit_range_.size()); - return {data_, bit_range_.start() + index}; - } - - MutableBitSpan slice(const IndexRange range) const - { - return {data_, bit_range_.slice(range)}; - } - - BitInt *data() const - { - return data_; - } - - const IndexRange &bit_range() const - { - return bit_range_; - } - - MutableBitIterator begin() const - { - return {data_, bit_range_.start()}; - } - - MutableBitIterator end() const - { - return {data_, bit_range_.one_after_last()}; - } - - operator BitSpan() const - { - return {data_, bit_range_}; - } - - /** Sets all referenced bits to 1. */ - void set_all() - { - const AlignedIndexRanges ranges = split_index_range_by_alignment(bit_range_, BitsPerInt); - { - BitInt &first_int = *int_containing_bit(data_, bit_range_.start()); - const BitInt first_int_mask = mask_range_bits(ranges.prefix.start() & BitIndexMask, - ranges.prefix.size()); - first_int |= first_int_mask; - } - { - BitInt *start = int_containing_bit(data_, ranges.aligned.start()); - const int64_t ints_to_fill = ranges.aligned.size() / BitsPerInt; - constexpr BitInt fill_value = BitInt(-1); - initialized_fill_n(start, ints_to_fill, fill_value); - } - { - BitInt &last_int = *int_containing_bit(data_, bit_range_.one_after_last() - 1); - const BitInt last_int_mask = mask_first_n_bits(ranges.suffix.size()); - last_int |= last_int_mask; - } - } - - /** Sets all referenced bits to 0. */ - void reset_all() - { - const AlignedIndexRanges ranges = split_index_range_by_alignment(bit_range_, BitsPerInt); - { - BitInt &first_int = *int_containing_bit(data_, bit_range_.start()); - const BitInt first_int_mask = mask_range_bits(ranges.prefix.start() & BitIndexMask, - ranges.prefix.size()); - first_int &= ~first_int_mask; - } - { - BitInt *start = int_containing_bit(data_, ranges.aligned.start()); - const int64_t ints_to_fill = ranges.aligned.size() / BitsPerInt; - constexpr BitInt fill_value = 0; - initialized_fill_n(start, ints_to_fill, fill_value); - } - { - BitInt &last_int = *int_containing_bit(data_, bit_range_.one_after_last() - 1); - const BitInt last_int_mask = mask_first_n_bits(ranges.suffix.size()); - last_int &= ~last_int_mask; - } - } - - /** Sets all referenced bits to either 0 or 1. */ - void set_all(const bool value) - { - if (value) { - this->set_all(); - } - else { - this->reset_all(); - } - } - - /** Same as #set_all to mirror #MutableSpan. */ - void fill(const bool value) - { - this->set_all(value); - } -}; - -inline std::ostream &operator<<(std::ostream &stream, const BitSpan &span) -{ - stream << "(Size: " << span.size() << ", "; - for (const BitRef bit : span) { - stream << bit; - } - stream << ")"; - return stream; -} - -inline std::ostream &operator<<(std::ostream &stream, const MutableBitSpan &span) -{ - return stream << BitSpan(span); -} - -} // namespace blender::bits - -namespace blender { -using bits::BitSpan; -using bits::MutableBitSpan; -} // namespace blender diff --git a/source/blender/blenlib/BLI_bit_vector.hh b/source/blender/blenlib/BLI_bit_vector.hh index 3c48d17703f..237bdce1452 100644 --- a/source/blender/blenlib/BLI_bit_vector.hh +++ b/source/blender/blenlib/BLI_bit_vector.hh @@ -38,11 +38,142 @@ #include #include "BLI_allocator.hh" -#include "BLI_bit_span.hh" +#include "BLI_index_range.hh" +#include "BLI_memory_utils.hh" #include "BLI_span.hh" namespace blender::bits { +/** + * 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 integer that the bit is in. */ + const IntType *ptr_; + /** All zeros except for a single one at the bit that is referenced. */ + IntType mask_; + + friend class MutableBitRef; + + public: + BitRef() = default; + + /** + * 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 IntType *ptr, const int64_t bit_index) + { + ptr_ = ptr + (bit_index >> BitToIntIndexShift); + mask_ = IntType(1) << (bit_index & BitIndexMask); + } + + /** + * Return true when the bit is currently 1 and false otherwise. + */ + bool test() const + { + const IntType value = *ptr_; + const IntType masked_value = value & mask_; + return masked_value != 0; + } + + operator bool() const + { + return this->test(); + } +}; + +/** + * Similar to #BitRef, but also allows changing the referenced bit. + */ +class MutableBitRef { + private: + /** Points to the integer that the bit is in. */ + IntType *ptr_; + /** All zeros except for a single one at the bit that is referenced. */ + IntType mask_; + + public: + MutableBitRef() = default; + + /** + * Reference a specific bit in an array. Note that #ptr does *not* have to point to the + * exact int the bit is in. + */ + MutableBitRef(IntType *ptr, const int64_t bit_index) + { + ptr_ = ptr + (bit_index >> BitToIntIndexShift); + mask_ = IntType(1) << IntType(bit_index & BitIndexMask); + } + + /** + * Support implicitly casting to a read-only #BitRef. + */ + operator BitRef() const + { + BitRef bit_ref; + bit_ref.ptr_ = ptr_; + bit_ref.mask_ = mask_; + return bit_ref; + } + + /** + * Return true when the bit is currently 1 and false otherwise. + */ + bool test() const + { + const IntType value = *ptr_; + const IntType masked_value = value & mask_; + return masked_value != 0; + } + + operator bool() const + { + return this->test(); + } + + /** + * Change the bit to a 1. + */ + void set() + { + *ptr_ |= mask_; + } + + /** + * Change the bit to a 0. + */ + void reset() + { + *ptr_ &= ~mask_; + } + + /** + * Change the bit to a 1 if #value is true and 0 otherwise. + */ + void set(const bool value) + { + if (value) { + this->set(); + } + else { + this->reset(); + } + } +}; + template< /** * Number of bits that can be stored in the vector without doing an allocation. @@ -62,13 +193,13 @@ class BitVector { static constexpr int64_t IntsInInlineBuffer = required_ints_for_bits(InlineBufferCapacity); static constexpr int64_t BitsInInlineBuffer = IntsInInlineBuffer * BitsPerInt; - static constexpr int64_t AllocationAlignment = alignof(BitInt); + static constexpr int64_t AllocationAlignment = alignof(IntType); /** * Points to the first integer used by the vector. It might point to the memory in the inline * buffer. */ - BitInt *data_; + IntType *data_; /** Current size of the vector in bits. */ int64_t size_in_bits_; @@ -80,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) @@ -88,7 +219,7 @@ class BitVector { data_ = inline_buffer_; size_in_bits_ = 0; capacity_in_bits_ = BitsInInlineBuffer; - uninitialized_fill_n(data_, IntsInInlineBuffer, BitInt(0)); + uninitialized_fill_n(data_, IntsInInlineBuffer, IntType(0)); } BitVector(NoExceptConstructor, Allocator allocator = {}) noexcept : BitVector(allocator) @@ -105,8 +236,8 @@ class BitVector { } else { /* Allocate a new array because the inline buffer is too small. */ - data_ = static_cast( - allocator_.allocate(ints_to_copy * sizeof(BitInt), AllocationAlignment, __func__)); + 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_; @@ -172,16 +303,6 @@ class BitVector { return move_assign_container(*this, std::move(other)); } - operator BitSpan() const - { - return {data_, IndexRange(size_in_bits_)}; - } - - operator MutableBitSpan() - { - return {data_, IndexRange(size_in_bits_)}; - } - /** * Number of bits in the bit vector. */ @@ -231,24 +352,80 @@ class BitVector { size_in_bits_++; } - BitIterator begin() const + class Iterator { + private: + const BitVector *vector_; + int64_t index_; + + public: + Iterator(const BitVector &vector, const int64_t index) : vector_(&vector), index_(index) + { + } + + Iterator &operator++() + { + index_++; + return *this; + } + + friend bool operator!=(const Iterator &a, const Iterator &b) + { + BLI_assert(a.vector_ == b.vector_); + return a.index_ != b.index_; + } + + BitRef operator*() const + { + return (*vector_)[index_]; + } + }; + + class MutableIterator { + private: + BitVector *vector_; + int64_t index_; + + public: + MutableIterator(BitVector &vector, const int64_t index) : vector_(&vector), index_(index) + { + } + + MutableIterator &operator++() + { + index_++; + return *this; + } + + friend bool operator!=(const MutableIterator &a, const MutableIterator &b) + { + BLI_assert(a.vector_ == b.vector_); + return a.index_ != b.index_; + } + + MutableBitRef operator*() const + { + return (*vector_)[index_]; + } + }; + + Iterator begin() const { - return {data_, 0}; + return {*this, 0}; } - BitIterator end() const + Iterator end() const { - return {data_, size_in_bits_}; + return {*this, size_in_bits_}; } - MutableBitIterator begin() + MutableIterator begin() { - return {data_, 0}; + return {*this, 0}; } - MutableBitIterator end() + MutableIterator end() { - return {data_, size_in_bits_}; + return {*this, size_in_bits_}; } /** @@ -264,8 +441,31 @@ class BitVector { } size_in_bits_ = new_size_in_bits; if (old_size_in_bits < new_size_in_bits) { - MutableBitSpan(data_, IndexRange(old_size_in_bits, new_size_in_bits - old_size_in_bits)) - .set_all(value); + this->fill_range(IndexRange(old_size_in_bits, new_size_in_bits - old_size_in_bits), value); + } + } + + /** + * Set #value for every element in #range. + */ + void fill_range(const IndexRange range, const bool value) + { + 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 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 int. */ + for (const int64_t i : aligned_ranges.suffix) { + (*this)[i].set(value); } } @@ -274,7 +474,7 @@ class BitVector { */ void fill(const bool value) { - MutableBitSpan(data_, size_in_bits_).set_all(value); + this->fill_range(IndexRange(0, size_in_bits_), value); } /** @@ -317,7 +517,7 @@ class BitVector { } BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity_in_bits, - const BitInt initial_value_for_new_ints = 0) + const IntType initial_value_for_new_ints = 0x00) { if (capacity_in_bits_ >= min_capacity_in_bits) { return; @@ -331,8 +531,8 @@ class BitVector { 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(); - BitInt *new_data = static_cast( - allocator_.allocate(new_capacity_in_ints * sizeof(BitInt), AllocationAlignment, __func__)); + 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 @@ -362,5 +562,7 @@ class BitVector { } // namespace blender::bits namespace blender { +using bits::BitRef; using bits::BitVector; +using bits::MutableBitRef; } // namespace blender diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index a283d77eafc..7fb7085360b 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -304,13 +304,6 @@ void rotate_eul(float beul[3], char axis, float angle); /* Order independent. */ -/** - * Manipulate `eul` so it's close to `oldrot` while representing the same rotation - * with the aim of having the minimum difference between all axes. - * - * This is typically done so interpolating the values between two euler rotations - * doesn't add undesired rotation (even rotating multiple times around one axis). - */ void compatible_eul(float eul[3], const float oldrot[3]); void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order); diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index bcc25db100c..16635df908b 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -457,8 +457,6 @@ if(WITH_GTESTS) tests/BLI_array_store_test.cc tests/BLI_array_test.cc tests/BLI_array_utils_test.cc - tests/BLI_bit_ref_test.cc - tests/BLI_bit_span_test.cc tests/BLI_bit_vector_test.cc tests/BLI_bitmap_test.cc tests/BLI_bounds_test.cc diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 49e6b61fad5..f47bc2d8ed7 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1490,18 +1490,15 @@ void rotate_eul(float beul[3], const char axis, const float angle) void compatible_eul(float eul[3], const float oldrot[3]) { - /* When the rotation exceeds 180 degrees, it can be wrapped by 360 degrees - * to produce a closer match. - * NOTE: Values between `pi` & `2 * pi` work, where `pi` has the lowest number of - * discontinuities and values approaching `2 * pi` center the resulting rotation around zero, - * at the expense of the result being less compatible, see !104856. */ - const float pi_thresh = (float)M_PI; + /* we could use M_PI as pi_thresh: which is correct but 5.1 gives better results. + * Checked with baking actions to fcurves - campbell */ + const float pi_thresh = (5.1f); const float pi_x2 = (2.0f * (float)M_PI); float deul[3]; uint i; - /* Correct differences around 360 degrees first. */ + /* correct differences of about 360 degrees first */ for (i = 0; i < 3; i++) { deul[i] = eul[i] - oldrot[i]; if (deul[i] > pi_thresh) { @@ -1514,17 +1511,29 @@ void compatible_eul(float eul[3], const float oldrot[3]) } } - uint j = 1, k = 2; - for (i = 0; i < 3; j = k, k = i++) { - /* Check if this axis of rotations larger than 180 degrees and - * the others are smaller than 90 degrees. */ - if (fabsf(deul[i]) > M_PI && fabsf(deul[j]) < M_PI_2 && fabsf(deul[k]) < M_PI_2) { - if (deul[i] > 0.0f) { - eul[i] -= pi_x2; - } - else { - eul[i] += pi_x2; - } + /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */ + if (fabsf(deul[0]) > 3.2f && fabsf(deul[1]) < 1.6f && fabsf(deul[2]) < 1.6f) { + if (deul[0] > 0.0f) { + eul[0] -= pi_x2; + } + else { + eul[0] += pi_x2; + } + } + if (fabsf(deul[1]) > 3.2f && fabsf(deul[2]) < 1.6f && fabsf(deul[0]) < 1.6f) { + if (deul[1] > 0.0f) { + eul[1] -= pi_x2; + } + else { + eul[1] += pi_x2; + } + } + if (fabsf(deul[2]) > 3.2f && fabsf(deul[0]) < 1.6f && fabsf(deul[1]) < 1.6f) { + if (deul[2] > 0.0f) { + eul[2] -= pi_x2; + } + else { + eul[2] += pi_x2; } } } diff --git a/source/blender/blenlib/tests/BLI_bit_ref_test.cc b/source/blender/blenlib/tests/BLI_bit_ref_test.cc deleted file mode 100644 index 2c880e4ea06..00000000000 --- a/source/blender/blenlib/tests/BLI_bit_ref_test.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#include "BLI_bit_ref.hh" - -#include "testing/testing.h" - -namespace blender::bits::tests { - -TEST(bit_ref, MaskFirstNBits) -{ - EXPECT_EQ(mask_first_n_bits(0), 0); - EXPECT_EQ(mask_first_n_bits(1), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001); - EXPECT_EQ(mask_first_n_bits(5), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'1111); - EXPECT_EQ(mask_first_n_bits(63), - 0b0111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111); - EXPECT_EQ(mask_first_n_bits(64), - 0b1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111); -} - -TEST(bit_ref, MaskLastNBits) -{ - EXPECT_EQ(mask_last_n_bits(0), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_last_n_bits(1), - 0b1000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_last_n_bits(5), - 0b1111'1000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_last_n_bits(63), - 0b1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1110); - EXPECT_EQ(mask_last_n_bits(64), - 0b1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111); -} - -TEST(bit_ref, MaskSingleBit) -{ - EXPECT_EQ(mask_single_bit(0), 1); - EXPECT_EQ(mask_single_bit(1), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010); - EXPECT_EQ(mask_single_bit(5), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010'0000); - EXPECT_EQ(mask_single_bit(63), - 0b1000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); -} - -TEST(bit_ref, IntContainingBit) -{ - std::array array; - uint64_t *data = array.data(); - EXPECT_EQ(int_containing_bit(data, 0), data); - EXPECT_EQ(int_containing_bit(data, 1), data); - EXPECT_EQ(int_containing_bit(data, 63), data); - EXPECT_EQ(int_containing_bit(data, 64), data + 1); - EXPECT_EQ(int_containing_bit(data, 65), data + 1); - EXPECT_EQ(int_containing_bit(data, 100), data + 1); - EXPECT_EQ(int_containing_bit(data, 127), data + 1); - EXPECT_EQ(int_containing_bit(data, 128), data + 2); - const uint64_t *data_const = data; - EXPECT_EQ(int_containing_bit(data_const, 0), data_const); - EXPECT_EQ(int_containing_bit(data_const, 1), data_const); - EXPECT_EQ(int_containing_bit(data_const, 63), data_const); - EXPECT_EQ(int_containing_bit(data_const, 64), data_const + 1); - EXPECT_EQ(int_containing_bit(data_const, 65), data_const + 1); - EXPECT_EQ(int_containing_bit(data_const, 100), data_const + 1); - EXPECT_EQ(int_containing_bit(data_const, 127), data_const + 1); - EXPECT_EQ(int_containing_bit(data_const, 128), data_const + 2); -} - -TEST(bit_ref, Test) -{ - uint64_t data = (1 << 3) | (1 << 7); - EXPECT_FALSE(BitRef(&data, 0).test()); - EXPECT_FALSE(BitRef(&data, 1).test()); - EXPECT_FALSE(BitRef(&data, 2).test()); - EXPECT_TRUE(BitRef(&data, 3).test()); - EXPECT_FALSE(BitRef(&data, 4)); - EXPECT_FALSE(BitRef(&data, 5)); - EXPECT_FALSE(BitRef(&data, 6)); - EXPECT_TRUE(BitRef(&data, 7)); - - EXPECT_FALSE(MutableBitRef(&data, 0).test()); - EXPECT_FALSE(MutableBitRef(&data, 1).test()); - EXPECT_FALSE(MutableBitRef(&data, 2).test()); - EXPECT_TRUE(MutableBitRef(&data, 3).test()); - EXPECT_FALSE(MutableBitRef(&data, 4)); - EXPECT_FALSE(MutableBitRef(&data, 5)); - EXPECT_FALSE(MutableBitRef(&data, 6)); - EXPECT_TRUE(MutableBitRef(&data, 7)); -} - -TEST(bit_ref, Set) -{ - uint64_t data = 0; - MutableBitRef(&data, 0).set(); - MutableBitRef(&data, 1).set(); - MutableBitRef(&data, 1).set(); - MutableBitRef(&data, 4).set(); - EXPECT_EQ(data, (1 << 0) | (1 << 1) | (1 << 4)); - MutableBitRef(&data, 5).set(true); - MutableBitRef(&data, 1).set(false); - EXPECT_EQ(data, (1 << 0) | (1 << 4) | (1 << 5)); -} - -TEST(bit_ref, Reset) -{ - uint64_t data = -1; - MutableBitRef(&data, 0).reset(); - MutableBitRef(&data, 2).reset(); - EXPECT_EQ(data, uint64_t(-1) & ~(1 << 0) & ~(1 << 2)); -} - -TEST(bit_ref, SetBranchless) -{ - uint64_t data = 0; - MutableBitRef(&data, 0).set_branchless(true); - EXPECT_EQ(data, 1); - MutableBitRef(&data, 0).set_branchless(false); - EXPECT_EQ(data, 0); - MutableBitRef(&data, 3).set_branchless(false); - MutableBitRef(&data, 4).set_branchless(true); - EXPECT_EQ(data, 16); - MutableBitRef(&data, 3).set_branchless(true); - MutableBitRef(&data, 4).set_branchless(true); - EXPECT_EQ(data, 24); -} - -TEST(bit_ref, Cast) -{ - uint64_t data = 0; - MutableBitRef mutable_ref(&data, 3); - BitRef ref = mutable_ref; - EXPECT_FALSE(ref); - mutable_ref.set(); - EXPECT_TRUE(ref); -} - -TEST(bit_ref, MaskRangeBits) -{ - EXPECT_EQ(mask_range_bits(0, 0), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_range_bits(0, 1), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001); - EXPECT_EQ(mask_range_bits(0, 5), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'1111); - EXPECT_EQ(mask_range_bits(64, 0), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_range_bits(63, 1), - 0b1000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_range_bits(59, 5), - 0b1111'1000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); - EXPECT_EQ(mask_range_bits(8, 3), - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0111'0000'0000); - EXPECT_EQ(mask_range_bits(0, 64), - 0b1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111); -} - -} // namespace blender::bits::tests diff --git a/source/blender/blenlib/tests/BLI_bit_span_test.cc b/source/blender/blenlib/tests/BLI_bit_span_test.cc deleted file mode 100644 index 4ffaadd1ddb..00000000000 --- a/source/blender/blenlib/tests/BLI_bit_span_test.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#include "BLI_bit_span.hh" - -#include "testing/testing.h" - -namespace blender::bits::tests { - -TEST(bit_span, DefaultConstructor) -{ - { - char buffer[sizeof(BitSpan)]; - memset(buffer, 0xff, sizeof(BitSpan)); - BitSpan &span = *new (buffer) BitSpan(); - EXPECT_TRUE(span.is_empty()); - EXPECT_EQ(span.size(), 0); - } - { - char buffer[sizeof(MutableBitSpan)]; - memset(buffer, 0xff, sizeof(MutableBitSpan)); - MutableBitSpan &span = *new (buffer) MutableBitSpan(); - EXPECT_TRUE(span.is_empty()); - EXPECT_EQ(span.size(), 0); - } -} - -TEST(bit_span, Iteration) -{ - uint64_t data = (1 << 2) | (1 << 3); - const BitSpan span(&data, 30); - EXPECT_EQ(span.size(), 30); - int index = 0; - for (const BitRef bit : span) { - EXPECT_EQ(bit.test(), ELEM(index, 2, 3)); - index++; - } -} - -TEST(bit_span, MutableIteration) -{ - uint64_t data = 0; - MutableBitSpan span(&data, 40); - EXPECT_EQ(span.size(), 40); - int index = 0; - for (MutableBitRef bit : span) { - bit.set(index % 4 == 0); - index++; - } - EXPECT_EQ(data, - 0b0000'0000'0000'0000'0000'0000'0001'0001'0001'0001'0001'0001'0001'0001'0001'0001); -} - -TEST(bit_span, SubscriptOperator) -{ - uint64_t data[2] = {0, 0}; - MutableBitSpan mutable_span(data, 128); - BitSpan span = mutable_span; - - EXPECT_EQ(mutable_span.data(), data); - EXPECT_EQ(mutable_span.bit_range(), IndexRange(128)); - EXPECT_EQ(span.data(), data); - EXPECT_EQ(span.bit_range(), IndexRange(128)); - - EXPECT_FALSE(mutable_span[5].test()); - EXPECT_FALSE(span[5].test()); - mutable_span[5].set(5); - EXPECT_TRUE(mutable_span[5].test()); - EXPECT_TRUE(span[5].test()); - - EXPECT_FALSE(mutable_span[120].test()); - EXPECT_FALSE(span[120].test()); - mutable_span[120].set(120); - EXPECT_TRUE(mutable_span[120].test()); - EXPECT_TRUE(span[120].test()); - - EXPECT_EQ(data[0], - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010'0000); - EXPECT_EQ(data[1], - 0b0000'0001'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000); -} - -TEST(bit_span, RangeConstructor) -{ - uint64_t data = 0; - MutableBitSpan mutable_span(&data, IndexRange(4, 3)); - BitSpan span = mutable_span; - - EXPECT_FALSE(mutable_span[1].test()); - EXPECT_FALSE(span[1].test()); - mutable_span[0].set(true); - mutable_span[1].set(true); - mutable_span[2].set(true); - mutable_span[0].set(false); - mutable_span[2].set(false); - EXPECT_TRUE(mutable_span[1].test()); - EXPECT_TRUE(span[1].test()); - - EXPECT_EQ(data, - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010'0000); -} - -TEST(bit_span, Set) -{ - uint64_t data = 0; - MutableBitSpan(&data, 64).set_all(true); - EXPECT_EQ(data, uint64_t(-1)); - MutableBitSpan(&data, 64).set_all(false); - EXPECT_EQ(data, uint64_t(0)); - - MutableBitSpan(&data, IndexRange(4, 8)).set_all(true); - EXPECT_EQ(data, - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'1111'1111'0000); - MutableBitSpan(&data, IndexRange(8, 30)).set_all(false); - - EXPECT_EQ(data, - 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'1111'0000); -} - -TEST(bit_span, SetSliced) -{ - std::array data; - memset(data.data(), 0, sizeof(data)); - MutableBitSpan span{data.data(), 640}; - span.slice(IndexRange(5, 500)).set_all(true); - - for (const int64_t i : IndexRange(640)) { - EXPECT_EQ(span[i], i >= 5 && i < 505); - } - - span.slice(IndexRange(10, 190)).set_all(false); - - for (const int64_t i : IndexRange(640)) { - EXPECT_EQ(span[i], (i >= 5 && i < 10) || (i >= 200 && i < 505)); - } -} - -} // namespace blender::bits::tests diff --git a/source/blender/blenlib/tests/BLI_bit_vector_test.cc b/source/blender/blenlib/tests/BLI_bit_vector_test.cc index a8e199f6f64..210f2be012d 100644 --- a/source/blender/blenlib/tests/BLI_bit_vector_test.cc +++ b/source/blender/blenlib/tests/BLI_bit_vector_test.cc @@ -6,7 +6,7 @@ #include "testing/testing.h" -namespace blender::bits::tests { +namespace blender::tests { TEST(bit_vector, DefaultConstructor) { @@ -183,4 +183,4 @@ TEST(bit_vector, AppendMany) EXPECT_TRUE(vec[5]); } -} // namespace blender::bits::tests +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc index b76f597ded6..8ec7ad85d9c 100644 --- a/source/blender/blenlib/tests/BLI_index_range_test.cc +++ b/source/blender/blenlib/tests/BLI_index_range_test.cc @@ -290,24 +290,6 @@ TEST(index_range, SplitByAlignment) EXPECT_EQ(ranges.aligned, IndexRange()); EXPECT_EQ(ranges.suffix, IndexRange()); } - { - AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(64), 64); - EXPECT_EQ(ranges.prefix, IndexRange()); - EXPECT_EQ(ranges.aligned, IndexRange(64)); - EXPECT_EQ(ranges.suffix, IndexRange()); - } - { - AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(64, 64), 64); - EXPECT_EQ(ranges.prefix, IndexRange()); - EXPECT_EQ(ranges.aligned, IndexRange(64, 64)); - EXPECT_EQ(ranges.suffix, IndexRange()); - } - { - AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(4, 8), 64); - EXPECT_EQ(ranges.prefix, IndexRange(4, 8)); - EXPECT_EQ(ranges.aligned, IndexRange()); - EXPECT_EQ(ranges.suffix, IndexRange()); - } } } // namespace blender::tests diff --git a/source/blender/bmesh/intern/bmesh_iterators.cc b/source/blender/bmesh/intern/bmesh_iterators.cc index c27d02b9a04..d712fe8c731 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.cc +++ b/source/blender/bmesh/intern/bmesh_iterators.cc @@ -211,7 +211,7 @@ void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], int BM_iter_mesh_bitmap_from_filter(const char itype, BMesh *bm, - blender::MutableBitSpan bitmap, + blender::BitVector<> &bitmap, bool (*test_fn)(BMElem *, void *user_data), void *user_data) { @@ -234,7 +234,7 @@ int BM_iter_mesh_bitmap_from_filter(const char itype, } int BM_iter_mesh_bitmap_from_filter_tessface(BMesh *bm, - blender::MutableBitSpan bitmap, + blender::BitVector<> &bitmap, bool (*test_fn)(BMFace *, void *user_data), void *user_data) { diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index a095e2831bf..d84f163f978 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -21,7 +21,7 @@ #include "BLI_mempool.h" #ifdef __cplusplus -# include "BLI_bit_span.hh" +# include "BLI_bit_vector.hh" #endif #ifdef __cplusplus @@ -228,14 +228,14 @@ void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], int BM_iter_mesh_bitmap_from_filter(char itype, BMesh *bm, - blender::MutableBitSpan bitmap, + blender::BitVector<> &bitmap, bool (*test_fn)(BMElem *, void *user_data), void *user_data); /** * Needed when we want to check faces, but return a loop aligned array. */ int BM_iter_mesh_bitmap_from_filter_tessface(BMesh *bm, - blender::MutableBitSpan bitmap, + blender::BitVector<> &bitmap, bool (*test_fn)(BMFace *, void *user_data), void *user_data); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl index 33217603b95..504b6ea2f44 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl @@ -59,9 +59,9 @@ void main() * IF PrimType == LineList: base_vertex_id = quad_id*2 * IF PrimType == LineStrip: base_vertex_id = quad_id * - * NOTE: This is currently used as LineList. + * Note: This is currently used as LineList. * - * NOTE: Primitive Restart Will not work with this setup as-is. We should avoid using + * Note: Primitive Restart Will not work with this setup as-is. We should avoid using * input primitive types which use restart indices. */ int base_vertex_id = quad_id * 2; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc index 2dcbc6d0dc6..233241ad776 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc @@ -557,7 +557,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr, const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false; if (mr->use_subsurf_fdots) { - const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc index 716acd6e2fd..bd04f6dbb03 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc @@ -46,7 +46,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr, GPUIndexBufBuilder *elb = static_cast(_userdata); if (mr->use_subsurf_fdots) { - const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; 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 51335d3cbb4..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 @@ -102,7 +102,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr, void *_data) { MeshExtract_EdgeFac_Data *data = static_cast(_data); - const BitSpan optimal_display_edges = mr->me->runtime->subsurf_optimal_display_edges; + 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; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc index 084f1cf25c6..b9f2917d0fe 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc @@ -76,7 +76,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, zero_v3(co); const MLoop *mloop = mr->mloop; - const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const int ml_index_end = mp->loopstart + mp->totloop; for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc index cc127fa9899..1ed6dc26b6f 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc @@ -74,7 +74,7 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr, void *_data) { MeshExtract_FdotUV_Data *data = static_cast(_data); - const BitSpan facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 7c894a4f616..298b48a4a90 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -47,7 +47,6 @@ #include "ED_anim_api.h" #include "ED_armature.h" #include "ED_keyframes_edit.h" /* XXX move the select modes out of there! */ -#include "ED_markers.h" #include "ED_object.h" #include "ED_screen.h" #include "ED_select_utils.h" @@ -3639,283 +3638,6 @@ static void ANIM_OT_channel_select_keys(wmOperatorType *ot) /** \} */ -/* -------------------------------------------------------------------- */ -/** \name View Channel Operator - * \{ */ - -static void get_normalized_fcurve_bounds(FCurve *fcu, - bAnimContext *ac, - const bAnimListElem *ale, - const bool include_handles, - const float range[2], - rctf *r_bounds) -{ - const bool fcu_selection_only = false; - BKE_fcurve_calc_bounds(fcu, - &r_bounds->xmin, - &r_bounds->xmax, - &r_bounds->ymin, - &r_bounds->ymax, - fcu_selection_only, - include_handles, - range); - const short mapping_flag = ANIM_get_normalization_flags(ac); - - const float min_height = 0.01f; - const float height = BLI_rctf_size_y(r_bounds); - if (height < min_height) { - r_bounds->ymin -= (min_height - height) / 2; - r_bounds->ymax += (min_height - height) / 2; - } - - float offset; - const float unit_fac = ANIM_unit_mapping_get_factor( - ac->scene, ale->id, fcu, mapping_flag, &offset); - - r_bounds->ymin = (r_bounds->ymin + offset) * unit_fac; - r_bounds->ymax = (r_bounds->ymax + offset) * unit_fac; -} - -static void get_gpencil_bounds(bGPDlayer *gpl, const float range[2], rctf *r_bounds) -{ - bool found_start = false; - int start_frame = 0; - int end_frame = 1; - LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { - if (gpf->framenum < range[0]) { - continue; - } - if (gpf->framenum > range[1]) { - break; - } - if (!found_start) { - start_frame = gpf->framenum; - found_start = true; - } - end_frame = gpf->framenum; - } - r_bounds->xmin = start_frame; - r_bounds->xmax = end_frame; - r_bounds->ymin = 0; - r_bounds->ymax = 1; -} - -static bool get_channel_bounds(bAnimContext *ac, - bAnimListElem *ale, - const float range[2], - const bool include_handles, - rctf *r_bounds) -{ - bool found_bounds = false; - switch (ale->datatype) { - case ALE_GPFRAME: { - bGPDlayer *gpl = (bGPDlayer *)ale->data; - get_gpencil_bounds(gpl, range, r_bounds); - found_bounds = true; - break; - } - case ALE_FCURVE: { - FCurve *fcu = (FCurve *)ale->key_data; - get_normalized_fcurve_bounds(fcu, ac, ale, include_handles, range, r_bounds); - found_bounds = true; - break; - } - } - return found_bounds; -} - -static void get_view_range(Scene *scene, const bool use_preview_range, float r_range[2]) -{ - if (use_preview_range && scene->r.flag & SCER_PRV_RANGE) { - r_range[0] = scene->r.psfra; - r_range[1] = scene->r.pefra; - } - else { - r_range[0] = -FLT_MAX; - r_range[1] = FLT_MAX; - } -} - -/* Pad the given rctf with regions that could block the view. - * For example Markers and Time Scrubbing. */ -static void add_region_padding(bContext *C, bAnimContext *ac, rctf *bounds) -{ - BLI_rctf_scale(bounds, 1.1f); - - const float pad_top = UI_TIME_SCRUB_MARGIN_Y; - const float pad_bottom = BLI_listbase_is_empty(ED_context_get_markers(C)) ? - V2D_SCROLL_HANDLE_HEIGHT : - UI_MARKER_MARGIN_Y; - BLI_rctf_pad_y(bounds, ac->region->winy, pad_bottom, pad_top); -} - -/* Find the window region in the bAnimContext area and move it to bounds. */ -static void move_graph_view(bContext *C, bAnimContext *ac, rctf *bounds, const int smooth_viewtx) -{ - LISTBASE_FOREACH (ARegion *, region, &ac->area->regionbase) { - if (region->regiontype == RGN_TYPE_WINDOW) { - UI_view2d_smooth_view(C, region, bounds, smooth_viewtx); - } - } -} - -static int graphkeys_view_selected_channels_exec(bContext *C, wmOperator *op) -{ - bAnimContext ac; - - /* Get editor data. */ - if (ANIM_animdata_get_context(C, &ac) == 0) { - return OPERATOR_CANCELLED; - } - - ListBase anim_data = {NULL, NULL}; - const int filter = (ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_DATA_VISIBLE | - ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); - size_t anim_data_length = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - if (anim_data_length == 0) { - WM_report(RPT_WARNING, "No channels to operate on"); - return OPERATOR_CANCELLED; - } - - float range[2]; - const bool use_preview_range = RNA_boolean_get(op->ptr, "use_preview_range"); - get_view_range(ac.scene, use_preview_range, range); - - rctf bounds = {.xmin = FLT_MAX, .xmax = -FLT_MAX, .ymin = FLT_MAX, .ymax = -FLT_MAX}; - - bAnimListElem *ale; - const bool include_handles = RNA_boolean_get(op->ptr, "include_handles"); - - bool valid_bounds = false; - for (ale = anim_data.first; ale; ale = ale->next) { - rctf channel_bounds; - const bool found_bounds = get_channel_bounds( - &ac, ale, range, include_handles, &channel_bounds); - if (found_bounds) { - BLI_rctf_union(&bounds, &channel_bounds); - valid_bounds = true; - } - } - - if (!valid_bounds) { - ANIM_animdata_freelist(&anim_data); - return OPERATOR_CANCELLED; - } - - add_region_padding(C, &ac, &bounds); - - const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); - move_graph_view(C, &ac, &bounds, smooth_viewtx); - - ANIM_animdata_freelist(&anim_data); - - return OPERATOR_FINISHED; -} - -static bool channel_view_poll(bContext *C) -{ - return ED_operator_action_active(C) || ED_operator_graphedit_active(C); -} - -static void ANIM_OT_channels_view_selected(wmOperatorType *ot) -{ - /* Identifiers */ - ot->name = "Frame Selected Channels"; - ot->idname = "ANIM_OT_channels_view_selected"; - ot->description = "Reset viewable area to show the selected channels"; - - /* API callbacks */ - ot->exec = graphkeys_view_selected_channels_exec; - ot->poll = channel_view_poll; - - ot->flag = 0; - - ot->prop = RNA_def_boolean(ot->srna, - "include_handles", - true, - "Include Handles", - "Include handles of keyframes when calculating extents"); - - ot->prop = RNA_def_boolean(ot->srna, - "use_preview_range", - true, - "Use Preview Range", - "Ignore frames outside of the preview range"); -} - -static int graphkeys_channel_view_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - bAnimContext ac; - - if (ANIM_animdata_get_context(C, &ac) == 0) { - return OPERATOR_CANCELLED; - } - - ListBase anim_data = {NULL, NULL}; - const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS | - ANIMFILTER_LIST_CHANNELS); - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - bAnimListElem *ale; - const int channel_index = animchannels_channel_get(&ac, event->mval); - ale = BLI_findlink(&anim_data, channel_index); - if (ale == NULL) { - ANIM_animdata_freelist(&anim_data); - return OPERATOR_CANCELLED; - } - - float range[2]; - const bool use_preview_range = RNA_boolean_get(op->ptr, "use_preview_range"); - get_view_range(ac.scene, use_preview_range, range); - - rctf bounds; - const bool include_handles = RNA_boolean_get(op->ptr, "include_handles"); - const bool found_bounds = get_channel_bounds(&ac, ale, range, include_handles, &bounds); - - if (!found_bounds) { - ANIM_animdata_freelist(&anim_data); - return OPERATOR_CANCELLED; - } - - add_region_padding(C, &ac, &bounds); - - const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); - move_graph_view(C, &ac, &bounds, smooth_viewtx); - - ANIM_animdata_freelist(&anim_data); - - return OPERATOR_FINISHED; -} - -static void ANIM_OT_channel_view_pick(wmOperatorType *ot) -{ - /* Identifiers */ - ot->name = "Frame Channel Under Cursor"; - ot->idname = "ANIM_OT_channel_view_pick"; - ot->description = "Reset viewable area to show the channel under the cursor"; - - /* API callbacks */ - ot->invoke = graphkeys_channel_view_pick_invoke; - ot->poll = channel_view_poll; - - ot->flag = 0; - - ot->prop = RNA_def_boolean(ot->srna, - "include_handles", - true, - "Include Handles", - "Include handles of keyframes when calculating extents"); - - ot->prop = RNA_def_boolean(ot->srna, - "use_preview_range", - true, - "Use Preview Range", - "Ignore frames outside of the preview range"); -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Operator Registration * \{ */ @@ -3935,9 +3657,6 @@ void ED_operatortypes_animchannels(void) WM_operatortype_append(ANIM_OT_channels_setting_disable); WM_operatortype_append(ANIM_OT_channels_setting_toggle); - WM_operatortype_append(ANIM_OT_channel_view_pick); - WM_operatortype_append(ANIM_OT_channels_view_selected); - WM_operatortype_append(ANIM_OT_channels_delete); /* XXX does this need to be a separate operator? */ diff --git a/source/blender/editors/asset/intern/asset_library_reference_enum.cc b/source/blender/editors/asset/intern/asset_library_reference_enum.cc index aab4bd12222..9aac90fc6e2 100644 --- a/source/blender/editors/asset/intern/asset_library_reference_enum.cc +++ b/source/blender/editors/asset/intern/asset_library_reference_enum.cc @@ -77,7 +77,11 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool if (include_generated) { const EnumPropertyItem generated_items[] = { - {ASSET_LIBRARY_ALL, "ALL", 0, "All", "Show assets from all of the listed asset libraries"}, + {ASSET_LIBRARY_ALL, + "ALL", + ICON_BLANK1, + "All", + "Show assets from all of the listed asset libraries"}, RNA_ENUM_ITEM_SEPR, {ASSET_LIBRARY_LOCAL, "LOCAL", @@ -86,7 +90,7 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool "Show the assets currently available in this Blender session"}, {ASSET_LIBRARY_ESSENTIALS, "ESSENTIALS", - 0, + ICON_BLANK1, "Essentials", "Show the basic building blocks and utilities coming with Blender"}, {0, nullptr, 0, nullptr, nullptr}, @@ -118,7 +122,7 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool const int enum_value = ED_asset_library_reference_to_enum_value(&library_reference); /* Use library path as description, it's a nice hint for users. */ EnumPropertyItem tmp = { - enum_value, user_library->name, ICON_NONE, user_library->name, user_library->path}; + enum_value, user_library->name, ICON_BLANK1, user_library->name, user_library->path}; RNA_enum_item_add(&item, &totitem, &tmp); } diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index a05ecfcaed3..080307ef2bd 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -1008,60 +1008,6 @@ static void CURVES_OT_select_linked(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int select_more_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_adjacent(curves, false); - /* 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_more(wmOperatorType *ot) -{ - ot->name = "Select More"; - ot->idname = __func__; - ot->description = "Grow the selection by one point"; - - ot->exec = select_more_exec; - ot->poll = editable_curves_point_domain_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static int select_less_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_adjacent(curves, true); - /* 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_less(wmOperatorType *ot) -{ - ot->name = "Select Less"; - ot->idname = __func__; - ot->description = "Shrink the selection by one point"; - - ot->exec = select_less_exec; - ot->poll = editable_curves_point_domain_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - namespace surface_set { static bool surface_set_poll(bContext *C) @@ -1187,8 +1133,6 @@ void ED_operatortypes_curves() 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_select_more); - WM_operatortype_append(CURVES_OT_select_less); WM_operatortype_append(CURVES_OT_surface_set); WM_operatortype_append(CURVES_OT_delete); } diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 086662cc85a..585498dd0fa 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -267,85 +267,6 @@ void select_linked(bke::CurvesGeometry &curves) selection.finish(); } -void select_adjacent(bke::CurvesGeometry &curves, const bool deselect) -{ - const OffsetIndices points_by_curve = curves.points_by_curve(); - bke::GSpanAttributeWriter selection = ensure_selection_attribute( - curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL); - const VArray cyclic = curves.cyclic(); - - if (deselect) { - invert_selection(selection.span); - } - - if (selection.span.type().is()) { - MutableSpan selection_typed = selection.span.typed(); - threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = points_by_curve[curve_i]; - - /* Handle all cases in the forward direction. */ - for (int point_i = points.first(); point_i < points.last(); point_i++) { - if (!selection_typed[point_i] && selection_typed[point_i + 1]) { - selection_typed[point_i] = true; - } - } - - /* Handle all cases in the backwards direction. */ - for (int point_i = points.last(); point_i > points.first(); point_i--) { - if (!selection_typed[point_i] && selection_typed[point_i - 1]) { - selection_typed[point_i] = true; - } - } - - /* Handle cyclic curve case. */ - if (cyclic[curve_i]) { - if (selection_typed[points.first()] != selection_typed[points.last()]) { - selection_typed[points.first()] = true; - selection_typed[points.last()] = true; - } - } - } - }); - } - else if (selection.span.type().is()) { - MutableSpan selection_typed = selection.span.typed(); - threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = points_by_curve[curve_i]; - - /* Handle all cases in the forward direction. */ - for (int point_i = points.first(); point_i < points.last(); point_i++) { - if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i + 1] > 0.0f)) { - selection_typed[point_i] = 1.0f; - } - } - - /* Handle all cases in the backwards direction. */ - for (int point_i = points.last(); point_i > points.first(); point_i--) { - if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i - 1] > 0.0f)) { - selection_typed[point_i] = 1.0f; - } - } - - /* Handle cyclic curve case. */ - if (cyclic[curve_i]) { - if (selection_typed[points.first()] != selection_typed[points.last()]) { - selection_typed[points.first()] = 1.0f; - selection_typed[points.last()] = 1.0f; - } - } - } - }); - } - - if (deselect) { - invert_selection(selection.span); - } - - selection.finish(); -} - void select_random(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, uint32_t random_seed, diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 178ec7a5b19..d9d6c0c2863 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -135,11 +135,6 @@ void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points); */ void select_linked(bke::CurvesGeometry &curves); -/** - * (De)select all the adjacent points of the current selected points. - */ -void select_adjacent(bke::CurvesGeometry &curves, bool deselect); - /** * Select random points or curves. * diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 16117937000..066aef1886d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -239,17 +239,6 @@ enum { UI_BUT_OVERRIDDEN = 1u << 31u, }; -/** #uiBut.dragflag */ -enum { - /** By default only the left part of a button triggers dragging. A questionable design to make - * the icon but not other parts of the button draggable. Set this flag so the entire button can - * be dragged. */ - UI_BUT_DRAG_FULL_BUT = (1 << 0), - - /* --- Internal flags. --- */ - UI_BUT_DRAGPOIN_FREE = (1 << 1), -}; - /* Default font size for normal text. */ #define UI_DEFAULT_TEXT_POINTS 11.0f @@ -892,9 +881,6 @@ bool UI_but_flag_is_set(uiBut *but, int flag); void UI_but_drawflag_enable(uiBut *but, int flag); void UI_but_drawflag_disable(uiBut *but, int flag); -void UI_but_dragflag_enable(uiBut *but, int flag); -void UI_but_dragflag_disable(uiBut *but, int flag); - void UI_but_disable(uiBut *but, const char *disabled_hint); void UI_but_type_set_menu_from_pulldown(uiBut *but); @@ -1803,12 +1789,9 @@ void UI_but_drag_set_id(uiBut *but, struct ID *id); /** * Set an image to display while dragging. This works for any drag type (`WM_DRAG_XXX`). * Not to be confused with #UI_but_drag_set_image(), which sets up dragging of an image. - * - * Sets #UI_BUT_DRAG_FULL_BUT so the full button can be dragged. */ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale); /** - * Sets #UI_BUT_DRAG_FULL_BUT so the full button can be dragged. * \param asset: May be passed from a temporary variable, drag data only stores a copy of this. */ void UI_but_drag_set_asset(uiBut *but, @@ -1825,8 +1808,6 @@ void UI_but_drag_set_name(uiBut *but, const char *name); * Value from button itself. */ void UI_but_drag_set_value(uiBut *but); - -/** Sets #UI_BUT_DRAG_FULL_BUT so the full button can be dragged. */ void UI_but_drag_set_image( uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, bool use_free); diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 652750dc531..6da7576d513 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -4224,10 +4224,6 @@ static uiBut *ui_def_but(uiBlock *block, but->flag |= UI_BUT_UNDO; } - if (ELEM(but->type, UI_BTYPE_COLOR)) { - but->dragflag |= UI_BUT_DRAG_FULL_BUT; - } - BLI_addtail(&block->buttons, but); if (block->curlayout) { @@ -4291,7 +4287,6 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p int totitems = 0; int categories = 0; int entries_nosepr_count = 0; - bool has_item_with_icon = false; for (const EnumPropertyItem *item = item_array; item->identifier; item++, totitems++) { if (!item->identifier[0]) { /* inconsistent, but menus with categories do not look good flipped */ @@ -4303,9 +4298,6 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p /* We do not want simple separators in `entries_nosepr_count`. */ continue; } - if (item->icon) { - has_item_with_icon = true; - } entries_nosepr_count++; } @@ -4410,18 +4402,11 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p uiItemS(column); } else { - int icon = item->icon; - /* Use blank icon if there is none for this item (but for some other one) to make sure labels - * align. */ - if (icon == ICON_NONE && has_item_with_icon) { - icon = ICON_BLANK1; - } - - if (icon) { + if (item->icon) { uiDefIconTextButI(block, UI_BTYPE_BUT_MENU, B_NOP, - icon, + item->icon, item->name, 0, 0, @@ -4600,7 +4585,15 @@ static uiBut *ui_def_but_rna(uiBlock *block, #endif } - icon = item[i].icon; + /* #ICON_BLANK1 can be used to add padding of the size of an icon. This is fine to align + * multiple items within a menu, but not for the menu button that only shows the label then. + */ + if ((type == UI_BTYPE_MENU) && (item[i].icon == ICON_BLANK1)) { + icon = ICON_NONE; + } + else { + icon = item[i].icon; + } } else { if (!str) { @@ -5894,16 +5887,6 @@ void UI_but_drawflag_disable(uiBut *but, int flag) but->drawflag &= ~flag; } -void UI_but_dragflag_enable(uiBut *but, int flag) -{ - but->dragflag |= flag; -} - -void UI_but_dragflag_disable(uiBut *but, int flag) -{ - but->dragflag &= ~flag; -} - void UI_but_disable(uiBut *but, const char *disabled_hint) { UI_but_flag_enable(but, UI_BUT_DISABLED); diff --git a/source/blender/editors/interface/interface_drag.cc b/source/blender/editors/interface/interface_drag.cc index 4156ec0f4a2..462cef50317 100644 --- a/source/blender/editors/interface/interface_drag.cc +++ b/source/blender/editors/interface/interface_drag.cc @@ -24,7 +24,6 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, const float scale) { but->imb = imb; but->imb_scale = scale; - UI_but_dragflag_enable(but, UI_BUT_DRAG_FULL_BUT); } void UI_but_drag_set_asset(uiBut *but, diff --git a/source/blender/editors/interface/interface_intern.hh b/source/blender/editors/interface/interface_intern.hh index accb6ecab2e..68a81de4e4a 100644 --- a/source/blender/editors/interface/interface_intern.hh +++ b/source/blender/editors/interface/interface_intern.hh @@ -86,6 +86,11 @@ enum { /* WARNING: rest of #uiBut.flag in UI_interface.h */ }; +/** #uiBut.dragflag */ +enum { + UI_BUT_DRAGPOIN_FREE = (1 << 0), +}; + /** #uiBut.pie_dir */ enum RadialDirection { UI_RADIAL_NONE = -1, diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc index 1d5eb9e7250..84e2b488ccb 100644 --- a/source/blender/editors/interface/interface_query.cc +++ b/source/blender/editors/interface/interface_query.cc @@ -247,7 +247,7 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv BLI_rcti_rctf_copy(&rect, &but->rect); - if (but->dragflag & UI_BUT_DRAG_FULL_BUT) { + if (but->imb || but->type == UI_BTYPE_COLOR) { /* use button size itself */ } else if (but->drawflag & UI_BUT_ICON_LEFT) { diff --git a/source/blender/editors/interface/interface_template_attribute_search.cc b/source/blender/editors/interface/interface_template_attribute_search.cc index 2ac8e96b996..55ca945671f 100644 --- a/source/blender/editors/interface/interface_template_attribute_search.cc +++ b/source/blender/editors/interface/interface_template_attribute_search.cc @@ -92,9 +92,15 @@ void attribute_search_add_items(StringRefNull str, StringSearch *search = BLI_string_search_new(); for (const GeometryAttributeInfo *item : infos) { + + /* Don't show the legacy "normal" attribute. */ + if (item->name == "normal" && item->domain == ATTR_DOMAIN_FACE) { + continue; + } if (!bke::allow_procedural_attribute_access(item->name)) { continue; } + BLI_string_search_add(search, item->name.c_str(), (void *)item, 0); } diff --git a/source/blender/editors/mesh/editmesh_mask_extract.cc b/source/blender/editors/mesh/editmesh_mask_extract.cc index 8dc08f233e9..83580b32884 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.cc +++ b/source/blender/editors/mesh/editmesh_mask_extract.cc @@ -285,7 +285,7 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op) params.add_solidify = RNA_boolean_get(op->ptr, "add_solidify"); /* Push an undo step prior to extraction. - * NOTE: A second push happens after the operator due to + * Note: A second push happens after the operator due to * the OPTYPE_UNDO flag; having an initial undo step here * is just needed to preserve the active object pointer. * diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 83ebabd3c26..7801741d5d8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -83,7 +83,7 @@ bool SCULPT_is_automasking_mode_enabled(const Sculpt *sd, bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, const Brush *br) { - if (ss && br && SCULPT_stroke_is_dynamic_topology(ss, br)) { + if (br && SCULPT_stroke_is_dynamic_topology(ss, br)) { return false; } if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_TOPOLOGY)) { diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.cc b/source/blender/editors/sculpt_paint/sculpt_cloth.cc index 6db4fe5b718..3ceab5431ec 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.cc +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.cc @@ -1571,13 +1571,8 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_stroke_id_next(ob); SCULPT_undo_push_begin(ob, op); - SCULPT_filter_cache_init(C, - ob, - sd, - SCULPT_UNDO_COORDS, - event->mval, - RNA_float_get(op->ptr, "area_normal_radius"), - RNA_float_get(op->ptr, "strength")); + 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, nullptr, ob); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.cc b/source/blender/editors/sculpt_paint/sculpt_filter_color.cc index 36d02c65605..3ca6449ad50 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.cc @@ -347,13 +347,8 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED; } - SCULPT_filter_cache_init(C, - ob, - sd, - SCULPT_UNDO_COLOR, - event->mval, - RNA_float_get(op->ptr, "area_normal_radius"), - RNA_float_get(op->ptr, "strength")); + SCULPT_filter_cache_init( + 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, nullptr, ob); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc index c10f4995057..82f89c7f8f9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc @@ -8,9 +8,7 @@ #include "MEM_guardedalloc.h" #include "BLI_hash.h" -#include "BLI_index_range.hh" #include "BLI_math.h" -#include "BLI_math_vector_types.hh" #include "BLI_task.h" #include "DNA_meshdata_types.h" @@ -25,7 +23,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_screen.h" #include "ED_view3d.h" #include "paint_intern.h" @@ -33,20 +30,14 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_prototypes.h" #include "UI_interface.h" -#include "UI_resources.h" #include "bmesh.h" #include #include -using blender::float2; -using blender::float3; -using blender::IndexRange; - void SCULPT_filter_to_orientation_space(float r_v[3], FilterCache *filter_cache) { switch (filter_cache->orientation) { @@ -105,14 +96,13 @@ void SCULPT_filter_cache_init(bContext *C, Sculpt *sd, const int undo_type, const int mval[2], - float area_normal_radius, - float start_strength) + float area_normal_radius) { SculptSession *ss = ob->sculpt; PBVH *pbvh = ob->sculpt->pbvh; ss->filter_cache = MEM_cnew(__func__); - ss->filter_cache->start_filter_strength = start_strength; + ss->filter_cache->random_seed = rand(); if (undo_type == SCULPT_UNDO_COLOR) { @@ -348,15 +338,6 @@ static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type) MESH_FILTER_SHARPEN); } -static bool sculpt_mesh_filter_is_continuous(eSculptMeshFilterType type) -{ - return (ELEM(type, - MESH_FILTER_SHARPEN, - MESH_FILTER_SMOOTH, - MESH_FILTER_RELAX, - MESH_FILTER_RELAX_FACE_SETS)); -} - static void mesh_filter_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict /*tls*/) @@ -398,8 +379,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, continue; } - if (ELEM(filter_type, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS) || - ss->filter_cache->no_orig_co) { + if (ELEM(filter_type, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS)) { copy_v3_v3(orig_co, vd.co); } else { @@ -701,16 +681,34 @@ static void mesh_filter_surface_smooth_displace_task_cb(void *__restrict userdat BKE_pbvh_vertex_iter_end; } -static void sculpt_mesh_filter_apply(bContext *C, wmOperator *op) +static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *event) { Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 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) { + SCULPT_filter_cache_free(ss); + SCULPT_undo_push_end(ob); + SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS); + return OPERATOR_FINISHED; + } + + if (event->type != MOUSEMOVE) { + return OPERATOR_RUNNING_MODAL; + } + + const float len = event->prev_press_xy[0] - event->xy[0]; + filter_strength = filter_strength * -len * 0.001f * UI_DPI_FAC; + SCULPT_vertex_random_access_ensure(ss); + bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type); + BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false); + SculptThreadedTaskData data{}; data.sd = sd; data.ob = ob; @@ -742,136 +740,22 @@ static void sculpt_mesh_filter_apply(bContext *C, wmOperator *op) } SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS); -} - -static void sculpt_mesh_update_strength(wmOperator *op, - SculptSession *ss, - float2 prev_press_mouse, - float2 mouse) -{ - const float len = prev_press_mouse[0] - mouse[0]; - - float filter_strength = ss->filter_cache->start_filter_strength * -len * 0.001f * UI_DPI_FAC; - RNA_float_set(op->ptr, "strength", filter_strength); -} -static void sculpt_mesh_filter_apply_with_history(bContext *C, wmOperator *op) -{ - /* Event history is only stored for smooth and relax filters. */ - if (!RNA_collection_length(op->ptr, "event_history")) { - sculpt_mesh_filter_apply(C, op); - return; - } - - Object *ob = CTX_data_active_object(C); - SculptSession *ss = ob->sculpt; - float2 start_mouse; - bool first = true; - float initial_strength = ss->filter_cache->start_filter_strength; - - RNA_BEGIN (op->ptr, item, "event_history") { - float2 mouse; - RNA_float_get_array(&item, "mouse_event", mouse); - - if (first) { - first = false; - start_mouse = mouse; - continue; - } - - sculpt_mesh_update_strength(op, ss, start_mouse, mouse); - sculpt_mesh_filter_apply(C, op); - } - RNA_END; - - RNA_float_set(op->ptr, "strength", initial_strength); -} - -static void sculpt_mesh_filter_end(bContext *C, wmOperator * /*op*/) -{ - Object *ob = CTX_data_active_object(C); - SculptSession *ss = ob->sculpt; - - SCULPT_filter_cache_free(ss); - SCULPT_undo_push_end(ob); - SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS); -} - -static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - Object *ob = CTX_data_active_object(C); - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - SculptSession *ss = ob->sculpt; - const eSculptMeshFilterType filter_type = eSculptMeshFilterType(RNA_enum_get(op->ptr, "type")); - - if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { - float initial_strength = ss->filter_cache->start_filter_strength; - sculpt_mesh_filter_end(C, op); - - /* Don't update strength property if we're storing an event history. */ - if (sculpt_mesh_filter_is_continuous(filter_type)) { - RNA_float_set(op->ptr, "strength", initial_strength); - } - - return OPERATOR_FINISHED; - } - - if (event->type != MOUSEMOVE) { - return OPERATOR_RUNNING_MODAL; - } - - /* Note: some filter types are continuous, for these we store an - * event history in RNA for continuous. - * This way the user can tweak the last operator properties - * or repeat the op and get expected results. */ - if (sculpt_mesh_filter_is_continuous(filter_type)) { - if (RNA_collection_length(op->ptr, "event_history") == 0) { - /* First entry is the start mouse position, event->prev_press_xy. */ - PointerRNA startptr; - RNA_collection_add(op->ptr, "event_history", &startptr); - - float2 mouse_start(float(event->prev_press_xy[0]), float(event->prev_press_xy[1])); - RNA_float_set_array(&startptr, "mouse_event", mouse_start); - } - - PointerRNA itemptr; - RNA_collection_add(op->ptr, "event_history", &itemptr); - - float2 mouse(float(event->xy[0]), float(event->xy[1])); - RNA_float_set_array(&itemptr, "mouse_event", mouse); - RNA_float_set(&itemptr, "pressure", WM_event_tablet_data(event, nullptr, nullptr)); - } - - float2 prev_mval(float(event->prev_press_xy[0]), float(event->prev_press_xy[1])); - float2 mval(float(event->xy[0]), float(event->xy[1])); - - sculpt_mesh_update_strength(op, ss, prev_mval, mval); - - bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type); - BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false); - - sculpt_mesh_filter_apply(C, op); return OPERATOR_RUNNING_MODAL; } -/* Returns OPERATOR_PASS_THROUGH on success. */ -static int sculpt_mesh_filter_start(bContext *C, wmOperator *op) +static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Object *ob = CTX_data_active_object(C); Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - int mval[2]; - RNA_int_get_array(op->ptr, "start_mouse", mval); - - const eSculptMeshFilterType filter_type = eSculptMeshFilterType(RNA_enum_get(op->ptr, "type")); - const bool use_automasking = SCULPT_is_automasking_enabled(sd, nullptr, nullptr); - const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type) || use_automasking; - - BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, false); SculptSession *ss = ob->sculpt; 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) { /* All axis are disabled, so the filter is not going to produce any deformation. */ @@ -884,25 +768,21 @@ static int sculpt_mesh_filter_start(bContext *C, wmOperator *op) /* Update the active face set manually as the paint cursor is not enabled when using the Mesh * Filter Tool. */ - float mval_fl[2] = {float(mval[0]), float(mval[1])}; + float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SculptCursorGeometryInfo sgi; SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); } SCULPT_vertex_random_access_ensure(ss); + BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, false); if (needs_topology_info) { SCULPT_boundary_info_ensure(ob); } SCULPT_undo_push_begin(ob, op); - SCULPT_filter_cache_init(C, - ob, - sd, - SCULPT_UNDO_COORDS, - mval, - RNA_float_get(op->ptr, "area_normal_radius"), - RNA_float_get(op->ptr, "strength")); + SCULPT_filter_cache_init( + C, ob, sd, SCULPT_UNDO_COORDS, 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; @@ -946,56 +826,12 @@ static int sculpt_mesh_filter_start(bContext *C, wmOperator *op) RNA_enum_get(op->ptr, "orientation")); ss->filter_cache->orientation = orientation; - return OPERATOR_PASS_THROUGH; -} - -static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - RNA_int_set_array(op->ptr, "start_mouse", event->mval); - int ret = sculpt_mesh_filter_start(C, op); - - if (ret == OPERATOR_PASS_THROUGH) { - WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; - } - - return ret; -} - -static int sculpt_mesh_filter_exec(bContext *C, wmOperator *op) -{ - int ret = sculpt_mesh_filter_start(C, op); - - if (ret == OPERATOR_PASS_THROUGH) { - Object *ob = CTX_data_active_object(C); - SculptSession *ss = ob->sculpt; - - int iterations = RNA_int_get(op->ptr, "iteration_count"); - bool has_history = RNA_collection_length(op->ptr, "event_history") > 0; - - if (!has_history) { - ss->filter_cache->no_orig_co = true; - } - - for (int i = 0; i < iterations; i++) { - sculpt_mesh_filter_apply_with_history(C, op); - - ss->filter_cache->no_orig_co = true; - } - - sculpt_mesh_filter_end(C, op); - - return OPERATOR_FINISHED; - } - - return ret; + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; } void SCULPT_mesh_filter_properties(wmOperatorType *ot) { - RNA_def_int_array( - ot->srna, "start_mouse", 2, nullptr, 0, 1 << 14, "Starting Mouse", "", 0, 1 << 14); - RNA_def_float( ot->srna, "area_normal_radius", @@ -1008,31 +844,6 @@ void SCULPT_mesh_filter_properties(wmOperatorType *ot) 1.0); RNA_def_float( ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f); - RNA_def_int(ot->srna, - "iteration_count", - 1, - 1, - 10000, - "Repeat", - "How many times to repeat the filter", - 1, - 100); - - /* Smooth filter requires entire event history. */ - PropertyRNA *prop = RNA_def_collection_runtime( - ot->srna, "event_history", &RNA_OperatorStrokeElement, "", ""); - RNA_def_property_flag(prop, PropertyFlag(int(PROP_HIDDEN) | int(PROP_SKIP_SAVE))); -} - -static void sculpt_mesh_ui_exec(bContext * /*C*/, wmOperator *op) -{ - uiLayout *layout = op->layout; - - uiItemR(layout, op->ptr, "strength", 0, nullptr, ICON_NONE); - uiItemR(layout, op->ptr, "iteration_count", 0, nullptr, ICON_NONE); - uiItemR(layout, op->ptr, "orientation", 0, nullptr, ICON_NONE); - layout = uiLayoutRow(layout, true); - uiItemR(layout, op->ptr, "deform_axis", UI_ITEM_R_EXPAND, nullptr, ICON_NONE); } void SCULPT_OT_mesh_filter(wmOperatorType *ot) @@ -1046,8 +857,6 @@ void SCULPT_OT_mesh_filter(wmOperatorType *ot) ot->invoke = sculpt_mesh_filter_invoke; ot->modal = sculpt_mesh_filter_modal; ot->poll = SCULPT_mode_poll; - ot->exec = sculpt_mesh_filter_exec; - ot->ui = sculpt_mesh_ui_exec; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index f80730da98c..5117b49407f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -494,8 +494,6 @@ struct FilterCache { float (*pre_smoothed_color)[4]; ViewContext vc; - float start_filter_strength; - bool no_orig_co; }; /** @@ -1429,8 +1427,7 @@ void SCULPT_filter_cache_init(bContext *C, Sculpt *sd, int undo_type, const int mval[2], - float area_normal_radius, - float start_strength); + float area_normal_radius); void SCULPT_filter_cache_free(SculptSession *ss); void SCULPT_mesh_filter_properties(wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index b8601984740..d9738b11215 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -229,8 +229,6 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - SCULPT_topology_islands_invalidate(ss); - /* Redraw. */ SCULPT_pbvh_clear(ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.cc b/source/blender/editors/sculpt_paint/sculpt_transform.cc index 17e23a726c1..9b487675c88 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.cc +++ b/source/blender/editors/sculpt_paint/sculpt_transform.cc @@ -58,7 +58,7 @@ void ED_sculpt_init_transform(bContext *C, Object *ob, const int mval[2], const SCULPT_vertex_random_access_ensure(ss); - SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS, mval, 5.0, 1.0f); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS, mval, 5.0); if (sd->transform_mode == SCULPT_TRANSFORM_MODE_RADIUS_ELASTIC) { ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL; diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c index 1bd28b068f9..bb8456f6486 100644 --- a/source/blender/editors/space_action/action_data.c +++ b/source/blender/editors/space_action/action_data.c @@ -590,7 +590,7 @@ void ED_animedit_unlink_action( if (nlt->strips.first == NULL) { BLI_assert(nstrip == NULL); - BKE_nlatrack_remove_and_free(&adt->nla_tracks, nlt, true); + BKE_nlatrack_free(&adt->nla_tracks, nlt, true); } } } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 34c89a13288..5a7be3be4a5 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -400,21 +400,6 @@ static void saction_channel_region_message_subscribe(const wmRegionMessageSubscr } } -static void action_clamp_scroll(ARegion *region) -{ - View2D *v2d = ®ion->v2d; - const float cur_height_y = BLI_rctf_size_y(&v2d->cur); - - if (BLI_rctf_size_y(&v2d->cur) > BLI_rctf_size_y(&v2d->tot)) { - v2d->cur.ymin = -cur_height_y; - v2d->cur.ymax = 0; - } - else if (v2d->cur.ymin < v2d->tot.ymin) { - v2d->cur.ymin = v2d->tot.ymin; - v2d->cur.ymax = v2d->cur.ymin + cur_height_y; - } -} - static void action_main_region_listener(const wmRegionListenerParams *params) { ARegion *region = params->region; @@ -875,13 +860,6 @@ static void action_blend_write(BlendWriter *writer, SpaceLink *sl) BLO_write_struct(writer, SpaceAction, sl); } -static void action_main_region_view2d_changed(const bContext *UNUSED(C), ARegion *region) -{ - /* V2D_KEEPTOT_STRICT cannot be used to clamp scrolling - * because it also clamps the x-axis to 0. */ - action_clamp_scroll(region); -} - void ED_spacetype_action(void) { SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype action"); @@ -914,7 +892,6 @@ void ED_spacetype_action(void) art->draw_overlay = action_main_region_draw_overlay; art->listener = action_main_region_listener; art->message_subscribe = saction_main_region_message_subscribe; - art->on_view2d_changed = action_main_region_view2d_changed; art->keymapflag = ED_KEYMAP_GIZMO | ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index bfc1903ae7d..97e6531eadd 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -128,55 +128,16 @@ static void draw_tile_background(const rcti *draw_rect, int colorid, int shade) UI_draw_roundbox_aa(&draw_rect_fl, true, 5.0f, color); } -static void file_but_enable_drag(uiBut *but, - const SpaceFile *sfile, - const FileDirEntry *file, - const char *path, - ImBuf *preview_image, - int icon, - float scale) -{ - ID *id; - - if ((id = filelist_file_get_id(file))) { - UI_but_drag_set_id(but, id); - if (preview_image) { - UI_but_drag_attach_image(but, preview_image, scale); - } - } - else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS && - (file->typeflag & FILE_TYPE_ASSET) != 0) { - char blend_path[FILE_MAX_LIBEXTRA]; - if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { - const int import_method = ED_fileselect_asset_import_method_get(sfile, file); - BLI_assert(import_method > -1); - - UI_but_drag_set_asset(but, - &(AssetHandle){.file_data = file}, - BLI_strdup(blend_path), - import_method, - icon, - preview_image, - scale); - } - } - else if (preview_image) { - UI_but_drag_set_image(but, BLI_strdup(path), icon, preview_image, scale, true); - } - else { - /* path is no more static, cannot give it directly to but... */ - UI_but_drag_set_path(but, BLI_strdup(path), true); - } -} - -static uiBut *file_add_icon_but(const SpaceFile *sfile, - uiBlock *block, - const char *path, - const rcti *tile_draw_rect, - int icon, - int width, - int height, - bool dimmed) +static void file_draw_icon(const SpaceFile *sfile, + uiBlock *block, + const FileDirEntry *file, + const char *path, + const rcti *tile_draw_rect, + int icon, + int width, + int height, + bool drag, + bool dimmed) { uiBut *but; @@ -190,7 +151,42 @@ static uiBut *file_add_icon_but(const SpaceFile *sfile, block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, a1, a2, NULL); UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path), MEM_freeN); - return but; + if (drag) { + /* TODO: duplicated from file_draw_preview(). */ + ID *id; + + if ((id = filelist_file_get_id(file))) { + UI_but_drag_set_id(but, id); + ImBuf *preview_image = filelist_file_getimage(file); + if (preview_image) { + UI_but_drag_attach_image(but, preview_image, UI_DPI_FAC); + } + } + else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS && + (file->typeflag & FILE_TYPE_ASSET) != 0) { + ImBuf *preview_image = filelist_file_getimage(file); + char blend_path[FILE_MAX_LIBEXTRA]; + if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { + const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + BLI_assert(asset_params != NULL); + + const int import_method = ED_fileselect_asset_import_method_get(sfile, file); + BLI_assert(import_method > -1); + + UI_but_drag_set_asset(but, + &(AssetHandle){.file_data = file}, + BLI_strdup(blend_path), + import_method, + icon, + preview_image, + UI_DPI_FAC); + } + } + else { + /* path is no more static, cannot give it directly to but... */ + UI_but_drag_set_path(but, BLI_strdup(path), true); + } + } } static void file_draw_string(int sx, @@ -301,50 +297,21 @@ void file_calc_previews(const bContext *C, ARegion *region) UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height); } -static void file_add_preview_drag_but(const SpaceFile *sfile, - uiBlock *block, - FileLayout *layout, - const FileDirEntry *file, - const char *path, - const rcti *tile_draw_rect, - ImBuf *preview_image, - const int icon, - const float scale) -{ - /* Invisible button for dragging. */ - rcti drag_rect = *tile_draw_rect; - /* A bit smaller than the full tile, to increase the gap between items that users can drag from - * for box select. */ - BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y); - - uiBut *but = uiDefBut(block, - UI_BTYPE_LABEL, - 0, - "", - drag_rect.xmin, - drag_rect.ymin, - BLI_rcti_size_x(&drag_rect), - BLI_rcti_size_y(&drag_rect), - NULL, - 0.0, - 0.0, - 0, - 0, - NULL); - file_but_enable_drag(but, sfile, file, path, preview_image, icon, scale); -} - -static void file_draw_preview(const FileDirEntry *file, +static void file_draw_preview(const SpaceFile *sfile, + uiBlock *block, + const FileDirEntry *file, + const char *path, const rcti *tile_draw_rect, const float icon_aspect, ImBuf *imb, const int icon, FileLayout *layout, const bool is_icon, + const bool drag, const bool dimmed, - const bool is_link, - float *r_scale) + const bool is_link) { + uiBut *but; float fx, fy; float dx, dy; int xco, yco; @@ -561,11 +528,62 @@ static void file_draw_preview(const FileDirEntry *file, immUnbindProgram(); } - GPU_blend(GPU_BLEND_NONE); + /* Invisible button for dragging. */ + rcti drag_rect = *tile_draw_rect; + /* A bit smaller than the full tile, to increase the gap between items that users can drag from + * for box select. */ + BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y); - if (r_scale) { - *r_scale = scale; + but = uiDefBut(block, + UI_BTYPE_LABEL, + 0, + "", + drag_rect.xmin, + drag_rect.ymin, + BLI_rcti_size_x(&drag_rect), + BLI_rcti_size_y(&drag_rect), + NULL, + 0.0, + 0.0, + 0, + 0, + NULL); + + /* Drag-region. */ + if (drag) { + ID *id; + + if ((id = filelist_file_get_id(file))) { + UI_but_drag_set_id(but, id); + UI_but_drag_attach_image(but, imb, scale); + } + /* path is no more static, cannot give it directly to but... */ + else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS && + (file->typeflag & FILE_TYPE_ASSET) != 0) { + char blend_path[FILE_MAX_LIBEXTRA]; + + if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { + const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + BLI_assert(asset_params != NULL); + + const int import_method = ED_fileselect_asset_import_method_get(sfile, file); + BLI_assert(import_method > -1); + + UI_but_drag_set_asset(but, + &(AssetHandle){.file_data = file}, + BLI_strdup(blend_path), + import_method, + icon, + imb, + scale); + } + } + else { + UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true); + } } + + GPU_blend(GPU_BLEND_NONE); } static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) @@ -1018,36 +1036,31 @@ void file_draw_list(const bContext *C, ARegion *region) is_icon = 1; } - float scale = 0; - file_draw_preview(file, + file_draw_preview(sfile, + block, + file, + path, &tile_draw_rect, thumb_icon_aspect, imb, icon, layout, is_icon, + do_drag, is_hidden, - is_link, - /* Returns the scale which is needed below. */ - &scale); - if (do_drag) { - file_add_preview_drag_but( - sfile, block, layout, file, path, &tile_draw_rect, imb, icon, scale); - } + is_link); } else { - const int icon = filelist_geticon(files, i, true); - uiBut *icon_but = file_add_icon_but(sfile, - block, - path, - &tile_draw_rect, - icon, - ICON_DEFAULT_WIDTH_SCALE, - ICON_DEFAULT_HEIGHT_SCALE, - is_hidden); - if (do_drag) { - file_but_enable_drag(icon_but, sfile, file, path, NULL, icon, UI_DPI_FAC); - } + file_draw_icon(sfile, + block, + file, + path, + &tile_draw_rect, + filelist_geticon(files, i, true), + ICON_DEFAULT_WIDTH_SCALE, + ICON_DEFAULT_HEIGHT_SCALE, + do_drag, + is_hidden); icon_ofs += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X; } diff --git a/source/blender/editors/space_graph/graph_view.c b/source/blender/editors/space_graph/graph_view.c index e6cbdd63ae6..f80c7c17c3a 100644 --- a/source/blender/editors/space_graph/graph_view.c +++ b/source/blender/editors/space_graph/graph_view.c @@ -91,7 +91,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, /* Get range. */ if (BKE_fcurve_calc_bounds( - fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles, NULL)) { + fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) { short mapping_flag = ANIM_get_normalization_flags(ac); /* Apply NLA scaling. */ diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 1d7645d4e67..a783ee32779 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -736,7 +736,7 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op)) } /* call delete on this track - deletes all strips too */ - BKE_nlatrack_remove_and_free(&adt->nla_tracks, nlt, true); + BKE_nlatrack_free(&adt->nla_tracks, nlt, true); ale->update = ANIM_UPDATE_DEPS; } } diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc index b11997ba1b6..ce37057bcf3 100644 --- a/source/blender/editors/space_node/node_view.cc +++ b/source/blender/editors/space_node/node_view.cc @@ -60,7 +60,7 @@ bool space_node_view_flag( int tot = 0; bool has_frame = false; if (snode.edittree) { - for (const bNode *node : snode.edittree->all_nodes()) { + LISTBASE_FOREACH (const bNode *, node, &snode.edittree->nodes) { if ((node->flag & node_flag) == node_flag) { BLI_rctf_union(&cur_new, &node->runtime->totr); tot++; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 2b7d981319c..9e255f12eb5 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -68,122 +68,6 @@ std::unique_ptr ExtraColumns::get_column_values( return std::make_unique(column_id.name, GVArray::ForSpan(*values)); } -static void add_mesh_debug_column_names( - const Mesh &mesh, - const eAttrDomain domain, - FunctionRef fn) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: - if (CustomData_has_layer(&mesh.vdata, CD_ORIGINDEX)) { - fn({(char *)"Original Index"}, false); - } - break; - case ATTR_DOMAIN_EDGE: - if (CustomData_has_layer(&mesh.edata, CD_ORIGINDEX)) { - fn({(char *)"Original Index"}, false); - } - fn({(char *)"Vertex 1"}, false); - fn({(char *)"Vertex 2"}, false); - break; - case ATTR_DOMAIN_FACE: - if (CustomData_has_layer(&mesh.pdata, CD_ORIGINDEX)) { - fn({(char *)"Original Index"}, false); - } - fn({(char *)"Corner Start"}, false); - fn({(char *)"Corner Size"}, false); - break; - case ATTR_DOMAIN_CORNER: - fn({(char *)"Vertex"}, false); - fn({(char *)"Edge"}, false); - break; - default: - BLI_assert_unreachable(); - break; - } -} - -static std::unique_ptr build_mesh_debug_columns(const Mesh &mesh, - const eAttrDomain domain, - const StringRef name) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: { - if (name == "Original Index") { - const int *data = static_cast( - CustomData_get_layer(&mesh.vdata, CD_ORIGINDEX)); - if (data) { - return std::make_unique(name, VArray::ForSpan({data, mesh.totvert})); - } - } - return {}; - } - case ATTR_DOMAIN_EDGE: { - const Span edges = mesh.edges(); - if (name == "Original Index") { - const int *data = static_cast( - CustomData_get_layer(&mesh.edata, CD_ORIGINDEX)); - if (data) { - return std::make_unique(name, VArray::ForSpan({data, mesh.totedge})); - } - } - if (name == "Vertex 1") { - return std::make_unique( - name, VArray::ForFunc(edges.size(), [edges](int64_t index) { - return edges[index].v1; - })); - } - if (name == "Vertex 2") { - return std::make_unique( - name, VArray::ForFunc(edges.size(), [edges](int64_t index) { - return edges[index].v2; - })); - } - return {}; - } - case ATTR_DOMAIN_FACE: { - const Span polys = mesh.polys(); - if (name == "Original Index") { - const int *data = static_cast( - CustomData_get_layer(&mesh.pdata, CD_ORIGINDEX)); - if (data) { - return std::make_unique(name, VArray::ForSpan({data, mesh.totpoly})); - } - } - if (name == "Corner Start") { - return std::make_unique( - name, VArray::ForFunc(polys.size(), [polys](int64_t index) { - return polys[index].loopstart; - })); - } - if (name == "Corner Size") { - return std::make_unique( - name, VArray::ForFunc(polys.size(), [polys](int64_t index) { - return polys[index].totloop; - })); - } - return {}; - } - case ATTR_DOMAIN_CORNER: { - const Span loops = mesh.loops(); - if (name == "Vertex") { - return std::make_unique( - name, - VArray::ForFunc(loops.size(), [loops](int64_t index) { return loops[index].v; })); - } - if (name == "Edge") { - return std::make_unique( - name, - VArray::ForFunc(loops.size(), [loops](int64_t index) { return loops[index].e; })); - } - return {}; - } - default: - BLI_assert_unreachable(); - return {}; - } -} - void GeometryDataSource::foreach_default_column_ids( FunctionRef fn) const { @@ -225,9 +109,17 @@ void GeometryDataSource::foreach_default_column_ids( fn({(char *)"Scale"}, false); } else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) { - const MeshComponent &component = static_cast(*component_); - if (const Mesh *mesh = component.get_for_read()) { - add_mesh_debug_column_names(*mesh, domain_, fn); + if (domain_ == ATTR_DOMAIN_EDGE) { + fn({(char *)"Vertex 1"}, false); + fn({(char *)"Vertex 2"}, false); + } + else if (domain_ == ATTR_DOMAIN_FACE) { + fn({(char *)"Corner Start"}, false); + fn({(char *)"Corner Size"}, false); + } + else if (domain_ == ATTR_DOMAIN_CORNER) { + fn({(char *)"Vertex"}, false); + fn({(char *)"Edge"}, false); } } } @@ -282,9 +174,51 @@ std::unique_ptr GeometryDataSource::get_column_values( else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) { const MeshComponent &component = static_cast(*component_); if (const Mesh *mesh = component.get_for_read()) { - if (std::unique_ptr values = build_mesh_debug_columns( - *mesh, domain_, column_id.name)) { - return values; + const Span edges = mesh->edges(); + const Span polys = mesh->polys(); + const Span loops = mesh->loops(); + + if (domain_ == ATTR_DOMAIN_EDGE) { + if (STREQ(column_id.name, "Vertex 1")) { + return std::make_unique( + column_id.name, VArray::ForFunc(edges.size(), [edges](int64_t index) { + return edges[index].v1; + })); + } + if (STREQ(column_id.name, "Vertex 2")) { + return std::make_unique( + column_id.name, VArray::ForFunc(edges.size(), [edges](int64_t index) { + return edges[index].v2; + })); + } + } + else if (domain_ == ATTR_DOMAIN_FACE) { + if (STREQ(column_id.name, "Corner Start")) { + return std::make_unique( + column_id.name, VArray::ForFunc(polys.size(), [polys](int64_t index) { + return polys[index].loopstart; + })); + } + if (STREQ(column_id.name, "Corner Size")) { + return std::make_unique( + column_id.name, VArray::ForFunc(polys.size(), [polys](int64_t index) { + return polys[index].totloop; + })); + } + } + else if (domain_ == ATTR_DOMAIN_CORNER) { + if (STREQ(column_id.name, "Vertex")) { + return std::make_unique( + column_id.name, VArray::ForFunc(loops.size(), [loops](int64_t index) { + return loops[index].v; + })); + } + if (STREQ(column_id.name, "Edge")) { + return std::make_unique( + column_id.name, VArray::ForFunc(loops.size(), [loops](int64_t index) { + return loops[index].e; + })); + } } } } diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 445fc79f320..fbd06791bd8 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1499,7 +1499,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh, const int totedge = mesh.totedge; /* Reuse the same buffer as #vert_dest_map. - * NOTE: the caller must be made aware of it changes. */ + * Note: the caller must be made aware of it changes. */ MutableSpan vert_group_map = vert_dest_map; WeldMesh weld_mesh; diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 609d6e52a3c..6b12512aea0 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -839,6 +839,7 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate( options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); + attributes_to_propagate.remove("normal"); attributes_to_propagate.remove("shade_smooth"); r_create_id = attributes_to_propagate.pop_try("id").has_value(); r_create_material_index = attributes_to_propagate.pop_try("material_index").has_value(); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 4cd2ae880ef..1624544a5ce 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -1895,7 +1895,7 @@ static void lineart_sort_adjacent_items(LineartAdjacentEdge *ai, int length) ai, ai + length, [](const LineartAdjacentEdge &p1, const LineartAdjacentEdge &p2) { int a = p1.v1 - p2.v1; int b = p1.v2 - p2.v2; - /* `parallel_sort()` requires `cmp()` to return true when the first element needs to appear + /* parallel_sort() requires cmp() to return true when the first element needs to appear * before the second element in the sorted array, false otherwise (strict weak ordering), * see https://en.cppreference.com/w/cpp/named_req/Compare. */ if (a < 0) { diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index c99716fbc4d..0e3057ee8c1 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -346,7 +346,7 @@ void gpu_shader_create_info_init() overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom; /* Workbench shadows. - * NOTE: Updates additional-info used by workbench shadow permutations. + * Note: Updates additional-info used by workbench shadow permutations. * Must be prepared prior to permutation preparation. */ workbench_shadow_manifold = workbench_shadow_manifold_no_geom; workbench_shadow_no_manifold = workbench_shadow_no_manifold_no_geom; diff --git a/source/blender/gpu/metal/mtl_immediate.mm b/source/blender/gpu/metal/mtl_immediate.mm index 25a12aac523..985b962cc99 100644 --- a/source/blender/gpu/metal/mtl_immediate.mm +++ b/source/blender/gpu/metal/mtl_immediate.mm @@ -339,7 +339,7 @@ void MTLImmediate::end() } break; case GPU_PRIM_LINE_LOOP: { /* Patch final vertex of line loop to close. Rendered using LineStrip. - * NOTE: vertex_len represents original length, however, allocated Metal + * Note: vertex_len represents original length, however, allocated Metal * buffer contains space for one extra vertex when LineLoop is used. */ uchar *buffer_data = reinterpret_cast(current_allocation_.data); memcpy(buffer_data + (vertex_len)*vertex_format.stride, diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index 6a69a66392e..3f145bd4763 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -640,10 +640,6 @@ void VKShader::compute_shader_from_glsl(MutableSpan sources) build_shader_module(sources, shaderc_compute_shader, &compute_module_); } -void VKShader::warm_cache(int /*limit*/) -{ -} - bool VKShader::finalize(const shader::ShaderCreateInfo *info) { if (compilation_failed_) { diff --git a/source/blender/gpu/vulkan/vk_shader.hh b/source/blender/gpu/vulkan/vk_shader.hh index 60924d35f21..6cc0e0c77e5 100644 --- a/source/blender/gpu/vulkan/vk_shader.hh +++ b/source/blender/gpu/vulkan/vk_shader.hh @@ -35,7 +35,7 @@ class VKShader : public Shader { void fragment_shader_from_glsl(MutableSpan sources) override; void compute_shader_from_glsl(MutableSpan sources) override; bool finalize(const shader::ShaderCreateInfo *info = nullptr) override; - void warm_cache(int limit) override; + void warm_cache(int limit) override{}; void transform_feedback_names_set(Span name_list, eGPUShaderTFBType geom_type) override; diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 43560c5ecba..fa2ef98d3df 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -593,7 +593,7 @@ static void rna_NlaTrack_remove( return; } - BKE_nlatrack_remove_and_free(&adt->nla_tracks, track, true); + BKE_nlatrack_free(&adt->nla_tracks, track, true); RNA_POINTER_INVALIDATE(track_ptr); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h index 2b01c98b35b..495c58d7b30 100644 --- a/source/blender/makesrna/intern/rna_mesh_utils.h +++ b/source/blender/makesrna/intern/rna_mesh_utils.h @@ -8,13 +8,13 @@ /* Macros to help reduce code clutter in rna_mesh.c */ -/* Define the accessors for a basic CustomDataLayer collection, skipping anonymous layers */ +/* Define the accessors for a basic CustomDataLayer collection */ #define DEFINE_CUSTOMDATA_LAYER_COLLECTION(collection_name, customdata_type, layer_type) \ /* check */ \ static int rna_##collection_name##_check(CollectionPropertyIterator *UNUSED(iter), void *data) \ { \ CustomDataLayer *layer = (CustomDataLayer *)data; \ - return (layer->anonymous_id != NULL || layer->type != layer_type); \ + return (layer->type != layer_type); \ } \ /* begin */ \ static void rna_Mesh_##collection_name##s_begin(CollectionPropertyIterator *iter, \ @@ -37,9 +37,7 @@ static int rna_Mesh_##collection_name##s_length(PointerRNA *ptr) \ { \ CustomData *data = rna_mesh_##customdata_type(ptr); \ - return data ? CustomData_number_of_layers(data, layer_type) - \ - CustomData_number_of_anonymous_layers(data, layer_type) : \ - 0; \ + return data ? CustomData_number_of_layers(data, layer_type) : 0; \ } \ /* index range */ \ static void rna_Mesh_##collection_name##_index_range( \ @@ -47,9 +45,7 @@ { \ CustomData *data = rna_mesh_##customdata_type(ptr); \ *min = 0; \ - *max = data ? CustomData_number_of_layers(data, layer_type) - \ - CustomData_number_of_anonymous_layers(data, layer_type) - 1 : \ - 0; \ + *max = data ? CustomData_number_of_layers(data, layer_type) - 1 : 0; \ *max = MAX2(0, *max); \ } diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index e7eed1c4dd3..0faf2da4f53 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -379,10 +379,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_new_nomain_from_template( mesh, int(maxVerts), int(maxEdges), 0, int(maxPolys) * 4, int(maxPolys)); - /* The modifier doesn't support original index mapping on the edge or face domains. Remove - * original index layers, since otherwise edges aren't displayed at all in wireframe view. */ - CustomData_free_layers(&result->edata, CD_ORIGINDEX, result->totedge); - CustomData_free_layers(&result->pdata, CD_ORIGINDEX, result->totedge); const float(*vert_positions_orig)[3] = BKE_mesh_vert_positions(mesh); const MEdge *medge_orig = BKE_mesh_edges(mesh); diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index c61bb8b4d8a..5b260a818a1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -64,6 +64,18 @@ struct IndexAttributes { /** \name Utility Functions * \{ */ +static Map gather_attributes_without_id( + const GeometrySet &geometry_set, + const GeometryComponentType component_type, + const AnonymousAttributePropagationInfo &propagation_info) +{ + Map attributes; + geometry_set.gather_attributes_for_propagation( + {component_type}, component_type, false, propagation_info, attributes); + attributes.remove("id"); + return attributes; +}; + static OffsetIndices accumulate_counts_to_offsets(const IndexMask selection, const VArray &counts, Array &r_offset_data) @@ -171,25 +183,39 @@ static void copy_stable_id_point(const OffsetIndices offsets, dst_attribute.finish(); } -static void copy_attributes_without_id(const OffsetIndices offsets, +static void copy_attributes_without_id(GeometrySet &geometry_set, + const GeometryComponentType component_type, + const eAttrDomain domain, + const OffsetIndices offsets, const IndexMask selection, const AnonymousAttributePropagationInfo &propagation_info, - const eAttrDomain domain, const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { - for (auto &attribute : bke::retrieve_attributes_for_transfer(src_attributes, - dst_attributes, - ATTR_DOMAIN_AS_MASK(domain), - propagation_info, - {"id"})) { - attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) { + const Map attributes = gather_attributes_without_id( + geometry_set, component_type, propagation_info); + + for (const Map::Item entry : attributes.items()) { + const AttributeIDRef attribute_id = entry.key; + GAttributeReader src_attribute = src_attributes.lookup(attribute_id); + if (!src_attribute || src_attribute.domain != domain) { + continue; + } + eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( + src_attribute.varray.type()); + GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span( + attribute_id, out_domain, data_type); + if (!dst_attribute) { + continue; + } + attribute_math::convert_to_static_type(data_type, [&](auto dummy) { using T = decltype(dummy); - const Span src = attribute.src.typed(); - MutableSpan dst = attribute.dst.span.typed(); + VArraySpan src = src_attribute.varray.typed(); + MutableSpan dst = dst_attribute.span.typed(); threaded_slice_fill(offsets, selection, src, dst); }); - attribute.dst.finish(); + dst_attribute.finish(); } } @@ -204,26 +230,42 @@ static void copy_attributes_without_id(const OffsetIndices offsets, * copied with an offset fill, otherwise a mapping is used. */ static void copy_curve_attributes_without_id( + const GeometrySet &geometry_set, const bke::CurvesGeometry &src_curves, const IndexMask selection, const OffsetIndices curve_offsets, const AnonymousAttributePropagationInfo &propagation_info, bke::CurvesGeometry &dst_curves) { + Map attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_CURVE, propagation_info); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); - for (auto &attribute : bke::retrieve_attributes_for_transfer(src_curves.attributes(), - dst_curves.attributes_for_write(), - ATTR_DOMAIN_MASK_ALL, - propagation_info, - {"id"})) { - attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) { - using T = decltype(dummy); - const Span src = attribute.src.typed(); - MutableSpan dst = attribute.dst.span.typed(); + for (const Map::Item entry : attributes.items()) { + const AttributeIDRef attribute_id = entry.key; + GAttributeReader src_attribute = src_curves.attributes().lookup(attribute_id); + if (!src_attribute) { + continue; + } - switch (attribute.meta_data.domain) { + eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( + src_attribute.varray.type()); + GSpanAttributeWriter dst_attribute = + dst_curves.attributes_for_write().lookup_or_add_for_write_only_span( + attribute_id, out_domain, data_type); + if (!dst_attribute) { + continue; + } + + attribute_math::convert_to_static_type(data_type, [&](auto dummy) { + using T = decltype(dummy); + VArraySpan src{src_attribute.varray.typed()}; + MutableSpan dst = dst_attribute.span.typed(); + + switch (out_domain) { case ATTR_DOMAIN_CURVE: threaded_slice_fill(curve_offsets, selection, src, dst); break; @@ -239,11 +281,10 @@ static void copy_curve_attributes_without_id( }); break; default: - BLI_assert_unreachable(); break; } }); - attribute.dst.finish(); + dst_attribute.finish(); } } @@ -353,7 +394,8 @@ static void duplicate_curves(GeometrySet &geometry_set, }); all_dst_offsets.last() = dst_points_num; - copy_curve_attributes_without_id(curves, selection, curve_offsets, propagation_info, new_curves); + copy_curve_attributes_without_id( + geometry_set, curves, selection, curve_offsets, propagation_info, new_curves); copy_stable_id_curves(curves, selection, curve_offsets, new_curves); @@ -380,6 +422,7 @@ static void duplicate_curves(GeometrySet &geometry_set, * copied with an offset fill, otherwise a mapping is used. */ static void copy_face_attributes_without_id( + GeometrySet &geometry_set, const Span edge_mapping, const Span vert_mapping, const Span loop_mapping, @@ -389,14 +432,31 @@ static void copy_face_attributes_without_id( const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { - for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_ALL, propagation_info, {"id"})) { - attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) { - using T = decltype(dummy); - const Span src = attribute.src.typed(); - MutableSpan dst = attribute.dst.span.typed(); + Map attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_MESH, propagation_info); - switch (attribute.meta_data.domain) { + for (const Map::Item entry : attributes.items()) { + const AttributeIDRef attribute_id = entry.key; + GAttributeReader src_attribute = src_attributes.lookup(attribute_id); + if (!src_attribute) { + continue; + } + + eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( + src_attribute.varray.type()); + GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span( + attribute_id, out_domain, data_type); + if (!dst_attribute) { + continue; + } + + attribute_math::convert_to_static_type(data_type, [&](auto dummy) { + using T = decltype(dummy); + VArraySpan src{src_attribute.varray.typed()}; + MutableSpan dst = dst_attribute.span.typed(); + + switch (out_domain) { case ATTR_DOMAIN_POINT: array_utils::gather(src, vert_mapping, dst); break; @@ -410,11 +470,10 @@ static void copy_face_attributes_without_id( array_utils::gather(src, loop_mapping, dst); break; default: - BLI_assert_unreachable(); break; } }); - attribute.dst.finish(); + dst_attribute.finish(); } } @@ -548,7 +607,8 @@ static void duplicate_faces(GeometrySet &geometry_set, new_mesh->loose_edges_tag_none(); - copy_face_attributes_without_id(edge_mapping, + copy_face_attributes_without_id(geometry_set, + edge_mapping, vert_mapping, loop_mapping, duplicates, @@ -586,6 +646,7 @@ static void duplicate_faces(GeometrySet &geometry_set, * copied with an offset fill, for point domain a mapping is used. */ static void copy_edge_attributes_without_id( + GeometrySet &geometry_set, const Span point_mapping, const OffsetIndices offsets, const IndexMask selection, @@ -593,18 +654,30 @@ static void copy_edge_attributes_without_id( const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { - for (auto &attribute : - bke::retrieve_attributes_for_transfer(src_attributes, - dst_attributes, - ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_EDGE, - propagation_info, - {"id"})) { - attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) { - using T = decltype(dummy); - const Span src = attribute.src.typed(); - MutableSpan dst = attribute.dst.span.typed(); + Map attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_MESH, propagation_info); - switch (attribute.meta_data.domain) { + for (const Map::Item entry : attributes.items()) { + const AttributeIDRef attribute_id = entry.key; + GAttributeReader src_attribute = src_attributes.lookup(attribute_id); + if (!src_attribute) { + continue; + } + + const eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( + src_attribute.varray.type()); + GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span( + attribute_id, out_domain, data_type); + if (!dst_attribute) { + continue; + } + attribute_math::convert_to_static_type(data_type, [&](auto dummy) { + using T = decltype(dummy); + VArraySpan src{src_attribute.varray.typed()}; + MutableSpan dst = dst_attribute.span.typed(); + + switch (out_domain) { case ATTR_DOMAIN_EDGE: threaded_slice_fill(offsets, selection, src, dst); break; @@ -612,11 +685,10 @@ static void copy_edge_attributes_without_id( array_utils::gather(src, point_mapping, dst); break; default: - BLI_assert_unreachable(); break; } }); - attribute.dst.finish(); + dst_attribute.finish(); } } @@ -719,7 +791,8 @@ static void duplicate_edges(GeometrySet &geometry_set, } }); - copy_edge_attributes_without_id(vert_orig_indices, + copy_edge_attributes_without_id(geometry_set, + vert_orig_indices, duplicates, selection, propagation_info, @@ -782,16 +855,32 @@ static void duplicate_points_curve(GeometrySet &geometry_set, } new_curve_offsets.last() = dst_num; - for (auto &attribute : bke::retrieve_attributes_for_transfer(src_curves.attributes(), - new_curves.attributes_for_write(), - ATTR_DOMAIN_MASK_ALL, - propagation_info, - {"id"})) { - attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) { + Map attributes = gather_attributes_without_id( + geometry_set, GEO_COMPONENT_TYPE_CURVE, propagation_info); + + for (const Map::Item entry : attributes.items()) { + const AttributeIDRef attribute_id = entry.key; + GAttributeReader src_attribute = src_curves.attributes().lookup(attribute_id); + if (!src_attribute) { + continue; + } + + eAttrDomain domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( + src_attribute.varray.type()); + GSpanAttributeWriter dst_attribute = + new_curves.attributes_for_write().lookup_or_add_for_write_only_span( + attribute_id, domain, data_type); + if (!dst_attribute) { + continue; + } + + attribute_math::convert_to_static_type(data_type, [&](auto dummy) { using T = decltype(dummy); - const Span src = attribute.src.typed(); - MutableSpan dst = attribute.dst.span.typed(); - switch (attribute.meta_data.domain) { + VArraySpan src{src_attribute.varray.typed()}; + MutableSpan dst = dst_attribute.span.typed(); + + switch (domain) { case ATTR_DOMAIN_CURVE: threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { @@ -804,11 +893,10 @@ static void duplicate_points_curve(GeometrySet &geometry_set, threaded_slice_fill(duplicates, selection, src, dst); break; default: - BLI_assert_unreachable(); break; } }); - attribute.dst.finish(); + dst_attribute.finish(); } copy_stable_id_point(duplicates, src_curves.attributes(), new_curves.attributes_for_write()); @@ -852,10 +940,12 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, Mesh *new_mesh = BKE_mesh_new_nomain(duplicates.total_size(), 0, 0, 0, 0); - copy_attributes_without_id(duplicates, + copy_attributes_without_id(geometry_set, + GEO_COMPONENT_TYPE_MESH, + ATTR_DOMAIN_POINT, + duplicates, selection, propagation_info, - ATTR_DOMAIN_POINT, mesh.attributes(), new_mesh->attributes_for_write()); @@ -900,10 +990,12 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, PointCloud *pointcloud = BKE_pointcloud_new_nomain(duplicates.total_size()); - copy_attributes_without_id(duplicates, + copy_attributes_without_id(geometry_set, + GEO_COMPONENT_TYPE_POINT_CLOUD, + ATTR_DOMAIN_POINT, + duplicates, selection, propagation_info, - ATTR_DOMAIN_POINT, src_points.attributes(), pointcloud->attributes_for_write()); @@ -1011,10 +1103,12 @@ static void duplicate_instances(GeometrySet &geometry_set, dst_instances->reference_handles().slice(range).fill(new_handle); } - copy_attributes_without_id(duplicates, + copy_attributes_without_id(geometry_set, + GEO_COMPONENT_TYPE_INSTANCES, + ATTR_DOMAIN_INSTANCE, + duplicates, selection, propagation_info, - ATTR_DOMAIN_INSTANCE, src_instances.attributes(), dst_instances->attributes_for_write()); 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 c5d2bbe1b65..63d84076654 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -471,6 +471,9 @@ static void extrude_mesh_edges(Mesh &mesh, } GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( id, meta_data.domain, meta_data.data_type); + if (!attribute) { + return true; /* Impossible to write the "normal" attribute. */ + } attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { using T = decltype(dummy); @@ -864,6 +867,9 @@ static void extrude_mesh_face_regions(Mesh &mesh, } GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( id, meta_data.domain, meta_data.data_type); + if (!attribute) { + return true; /* Impossible to write the "normal" attribute. */ + } attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { using T = decltype(dummy); @@ -1152,6 +1158,9 @@ static void extrude_individual_mesh_faces(Mesh &mesh, } GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( id, meta_data.domain, meta_data.data_type); + if (!attribute) { + return true; /* Impossible to write the "normal" attribute. */ + } attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { using T = decltype(dummy); diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index 97a6a925aee..8652493b49b 100644 --- a/source/blender/nodes/intern/node_common.cc +++ b/source/blender/nodes/intern/node_common.cc @@ -78,14 +78,16 @@ bool node_group_poll_instance(const bNode *node, const bNodeTree *nodetree, const char **disabled_hint) { - if (!node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) { - return false; + if (node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) { + const bNodeTree *grouptree = (const bNodeTree *)node->id; + if (grouptree) { + return nodeGroupPoll(nodetree, grouptree, disabled_hint); + } + + return true; /* without a linked node tree, group node is always ok */ } - const bNodeTree *grouptree = reinterpret_cast(node->id); - if (!grouptree) { - return true; - } - return nodeGroupPoll(nodetree, grouptree, disabled_hint); + + return false; } bool nodeGroupPoll(const bNodeTree *nodetree, @@ -112,9 +114,10 @@ bool nodeGroupPoll(const bNodeTree *nodetree, return false; } - for (const bNode *node : grouptree->all_nodes()) { + LISTBASE_FOREACH (const bNode *, node, &grouptree->nodes) { if (node->typeinfo->poll_instance && - !node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) { + !node->typeinfo->poll_instance( + const_cast(node), const_cast(nodetree), r_disabled_hint)) { return false; } } diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c index 190a3768286..ace8ccdeb2a 100644 --- a/source/blender/python/mathutils/mathutils_kdtree.c +++ b/source/blender/python/mathutils/mathutils_kdtree.c @@ -394,7 +394,7 @@ PyTypeObject PyKDTree_Type = { /*tp_setattro*/ NULL, /*tp_as_buffer*/ NULL, /*tp_flags*/ Py_TPFLAGS_DEFAULT, - /*tp_doc*/ py_KDtree_doc, + /*Documentation string*/ py_KDtree_doc, /*tp_traverse*/ NULL, /*tp_clear*/ NULL, /*tp_richcompare*/ NULL,