diff options
author | Hans Goudey <h.goudey@me.com> | 2021-07-13 18:48:37 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-07-13 18:48:37 +0300 |
commit | 903b786f69af342c5eda5c58ab25d827369c09cb (patch) | |
tree | 7f407a929a068c92df1860d0083897b426e04318 | |
parent | 56ca4fe5bb3c3d8cd92a1c99fc83856aaefdd0c2 (diff) | |
parent | 2373a2196e21b35998961fff2f53c5fa98036cd8 (diff) |
Merge branch 'master' into refactor-vertex-group-namesrefactor-vertex-group-names
520 files changed, 6898 insertions, 3935 deletions
diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index fb79eee62be..62b4602a998 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -164,6 +164,7 @@ endif() if(UNIX AND NOT APPLE) include(cmake/libglu.cmake) include(cmake/mesa.cmake) + include(cmake/wayland_protocols.cmake) endif() include(cmake/harvest.cmake) diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index 27351ddee45..db90e9b40e9 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -87,6 +87,7 @@ download_source(LIBGLU) download_source(MESA) download_source(NASM) download_source(XR_OPENXR_SDK) +download_source(WL_PROTOCOLS) download_source(ISPC) download_source(GMP) download_source(POTRACE) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index fc7e652a028..b94790507b2 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -126,6 +126,8 @@ if(UNIX AND NOT APPLE) harvest(xml2/include xml2/include "*.h") harvest(xml2/lib xml2/lib "*.a") + + harvest(wayland-protocols/share/wayland-protocols wayland-protocols/share/wayland-protocols/ "*.xml") else() harvest(blosc/lib openvdb/lib "*.a") harvest(xml2/lib opencollada/lib "*.a") diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 38cadff2202..bb0ee961f05 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -456,12 +456,18 @@ set(NASM_HASH aded8b796c996a486a56e0515c83e414116decc3b184d88043480b32eb0a8589) set(NASM_HASH_TYPE SHA256) set(NASM_FILE nasm-${NASM_VERSION}.tar.gz) -set(XR_OPENXR_SDK_VERSION 1.0.14) +set(XR_OPENXR_SDK_VERSION 1.0.17) set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz) -set(XR_OPENXR_SDK_HASH 0df6b2fd6045423451a77ff6bc3e1a75) +set(XR_OPENXR_SDK_HASH bf0fd8828837edff01047474e90013e1) set(XR_OPENXR_SDK_HASH_TYPE MD5) set(XR_OPENXR_SDK_FILE OpenXR-SDK-${XR_OPENXR_SDK_VERSION}.tar.gz) +set(WL_PROTOCOLS_VERSION 1.21) +set(WL_PROTOCOLS_FILE wayland-protocols-${WL_PROTOCOLS_VERSION}.tar.gz) +set(WL_PROTOCOLS_URI https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/${WL_PROTOCOLS_VERSION}/${WL_PROTOCOLS_FILE}) +set(WL_PROTOCOLS_HASH af5ca07e13517cdbab33504492cef54a) +set(WL_PROTOCOLS_HASH_TYPE MD5) + if(BLENDER_PLATFORM_ARM) # Unreleased version with macOS arm support. set(ISPC_URI https://github.com/ispc/ispc/archive/f5949c055eb9eeb93696978a3da4bfb3a6a30b35.zip) diff --git a/build_files/build_environment/cmake/wayland_protocols.cmake b/build_files/build_environment/cmake/wayland_protocols.cmake new file mode 100644 index 00000000000..02db453be42 --- /dev/null +++ b/build_files/build_environment/cmake/wayland_protocols.cmake @@ -0,0 +1,27 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ***** END GPL LICENSE BLOCK ***** + +ExternalProject_Add(external_wayland_protocols + URL file://${PACKAGE_DIR}/${WL_PROTOCOLS_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${WL_PROTOCOLS_HASH_TYPE}=${WL_PROTOCOLS_HASH} + PREFIX ${BUILD_DIR}/wayland-protocols + CONFIGURE_COMMAND meson --prefix ${LIBDIR}/wayland-protocols . ../external_wayland_protocols -Dtests=false + BUILD_COMMAND ninja + INSTALL_COMMAND ninja install +) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 22fb6602d7a..c5b7198d012 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -572,7 +572,7 @@ FFMPEG_FORCE_REBUILD=false FFMPEG_SKIP=false _ffmpeg_list_sep=";" -XR_OPENXR_VERSION="1.0.14" +XR_OPENXR_VERSION="1.0.17" XR_OPENXR_VERSION_SHORT="1.0" XR_OPENXR_VERSION_MIN="1.0.8" XR_OPENXR_VERSION_MAX="2.0" @@ -1108,9 +1108,9 @@ FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" ) XR_OPENXR_USE_REPO=false XR_OPENXR_SOURCE=("https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_VERSION}.tar.gz") -#~ XR_OPENXR_SOURCE_REPO=("https://github.com/KhronosGroup/OpenXR-SDK.git") -#~ XR_OPENXR_REPO_UID="5900c51562769b03bea699dc0352cae56acb6419d" -#~ XR_OPENXR_REPO_BRANCH="master" +XR_OPENXR_SOURCE_REPO=("https://github.com/KhronosGroup/OpenXR-SDK.git") +XR_OPENXR_REPO_UID="bf21ccb1007bb531b45d9978919a56ea5059c245" +XR_OPENXR_REPO_BRANCH="master" # C++11 is required now CXXFLAGS_BACK=$CXXFLAGS @@ -1128,6 +1128,7 @@ Those libraries should be available as packages in all recent distributions (opt * Basics of dev environment (cmake, gcc, svn , git, ...). * libjpeg, libpng, libtiff, [openjpeg2], [libopenal]. * libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed). + * libwayland-client0, libwayland-cursor0, libwayland-egl1, libxkbcommon0, libdbus-1-3, libegl1 (Wayland) * libsqlite3, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp. * libsdl2, libglew, libpugixml, libpotrace, [libgmp], [libglewmx], fontconfig, [libharu/libhpdf].\"" @@ -2737,7 +2738,7 @@ _init_openvdb() { _git=false _inst=$INST/openvdb-$OPENVDB_VERSION_SHORT _inst_shortcut=$INST/openvdb - + _openvdb_source=$OPENVDB_SOURCE if [ "$WITH_NANOVDB" = true ]; then _openvdb_source=$NANOVDB_SOURCE @@ -2842,7 +2843,7 @@ compile_OPENVDB() { if [ -d $INST/blosc ]; then cmake_d="$cmake_d -D Blosc_ROOT=$INST/blosc" fi - + cmake $cmake_d .. make -j$THREADS install @@ -3839,6 +3840,7 @@ install_DEB() { _packages="gawk cmake cmake-curses-gui build-essential libjpeg-dev libpng-dev libtiff-dev \ git libfreetype6-dev libfontconfig-dev libx11-dev flex bison libxxf86vm-dev \ libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \ + libwayland-dev wayland-protocols libegl-dev libxkbcommon-dev libdbus-1-dev linux-libc-dev \ libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \ libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \ libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \ @@ -4508,6 +4510,7 @@ install_RPM() { _packages="gcc gcc-c++ git make cmake tar bzip2 xz findutils flex bison fontconfig-devel \ libtiff-devel libjpeg-devel libpng-devel sqlite-devel fftw-devel SDL2-devel \ libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \ + wayland-devel wayland-protocols-devel mesa-libEGL-devel libxkbcommon-devel dbus-devel kernel-headers \ wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \ glew-devel yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV patch \ libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel \ diff --git a/build_files/build_environment/patches/ffmpeg.diff b/build_files/build_environment/patches/ffmpeg.diff index e195ca272de..5a50a3f8756 100644 --- a/build_files/build_environment/patches/ffmpeg.diff +++ b/build_files/build_environment/patches/ffmpeg.diff @@ -68,3 +68,32 @@ + return ret; } +--- a/libavcodec/rl.c ++++ b/libavcodec/rl.c +@@ -71,7 +71,7 @@ av_cold void ff_rl_init(RLTable *rl, + av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) + { + int i, q; +- VLC_TYPE table[1500][2] = {{0}}; ++ VLC_TYPE (*table)[2] = av_calloc(sizeof(VLC_TYPE), 1500 * 2); + VLC vlc = { .table = table, .table_allocated = static_size }; + av_assert0(static_size <= FF_ARRAY_ELEMS(table)); + init_vlc(&vlc, 9, rl->n + 1, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); +@@ -80,8 +80,10 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) + int qmul = q * 2; + int qadd = (q - 1) | 1; + +- if (!rl->rl_vlc[q]) ++ if (!rl->rl_vlc[q]){ ++ av_free(table); + return; ++ } + + if (q == 0) { + qmul = 1; +@@ -113,4 +115,5 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) + rl->rl_vlc[q][i].run = run; + } + } ++ av_free(table); + } diff --git a/build_files/windows/autodetect_msvc.cmd b/build_files/windows/autodetect_msvc.cmd index 6cee4765b93..a4ab8929040 100644 --- a/build_files/windows/autodetect_msvc.cmd +++ b/build_files/windows/autodetect_msvc.cmd @@ -1,9 +1,9 @@ echo No explicit msvc version requested, autodetecting version. -call "%~dp0\detect_msvc2017.cmd" +call "%~dp0\detect_msvc2019.cmd" if %ERRORLEVEL% EQU 0 goto DetectionComplete -call "%~dp0\detect_msvc2019.cmd" +call "%~dp0\detect_msvc2017.cmd" if %ERRORLEVEL% EQU 0 goto DetectionComplete call "%~dp0\detect_msvc2022.cmd" diff --git a/doc/python_api/examples/bpy.app.handlers.2.py b/doc/python_api/examples/bpy.app.handlers.2.py index aaaedeabecb..d514fa3fa4b 100644 --- a/doc/python_api/examples/bpy.app.handlers.2.py +++ b/doc/python_api/examples/bpy.app.handlers.2.py @@ -12,6 +12,7 @@ such cases, lock the interface (Render → Lock Interface or Below is an example of a mesh that is altered from a handler: """ + def frame_change_pre(scene): # A triangle that shifts in the z direction zshift = scene.frame_current * 0.1 diff --git a/doc/python_api/examples/bpy.app.timers.5.py b/doc/python_api/examples/bpy.app.timers.5.py index 821a047d7c7..dda5ea12e73 100644 --- a/doc/python_api/examples/bpy.app.timers.5.py +++ b/doc/python_api/examples/bpy.app.timers.5.py @@ -16,10 +16,12 @@ execution_queue = queue.Queue() def run_in_main_thread(function): execution_queue.put(function) + def execute_queued_functions(): while not execution_queue.empty(): function = execution_queue.get() function() return 1.0 + bpy.app.timers.register(execute_queued_functions) diff --git a/doc/python_api/examples/bpy.msgbus.1.py b/doc/python_api/examples/bpy.msgbus.1.py index 21198471ffa..8164272d521 100644 --- a/doc/python_api/examples/bpy.msgbus.1.py +++ b/doc/python_api/examples/bpy.msgbus.1.py @@ -31,11 +31,13 @@ owner = object() subscribe_to = bpy.context.object.location + def msgbus_callback(*args): # This will print: # Something changed! (1, 2, 3) print("Something changed!", args) + bpy.msgbus.subscribe_rna( key=subscribe_to, owner=owner, diff --git a/doc/python_api/examples/bpy.types.Depsgraph.7.py b/doc/python_api/examples/bpy.types.Depsgraph.7.py index 11982730fc9..afea8dfd618 100644 --- a/doc/python_api/examples/bpy.types.Depsgraph.7.py +++ b/doc/python_api/examples/bpy.types.Depsgraph.7.py @@ -44,7 +44,7 @@ class OBJECT_OT_object_to_curve(bpy.types.Operator): # Remove temporary curve. obj.to_curve_clear() # Invoke to_curve() with applying modifiers. - curve_with_modifiers = obj.to_curve(depsgraph, apply_modifiers = True) + curve_with_modifiers = obj.to_curve(depsgraph, apply_modifiers=True) self.report({'INFO'}, f"{len(curve_with_modifiers.splines)} splines in new curve with modifiers.") # Remove temporary curve. obj.to_curve_clear() diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py index 334a606055a..be164a03028 100644 --- a/doc/python_api/examples/gpu.6.py +++ b/doc/python_api/examples/gpu.6.py @@ -21,6 +21,7 @@ batch = batch_for_shader( }, ) + def draw(): shader.bind() shader.uniform_sampler("image", texture) diff --git a/intern/cycles/blender/blender_image.cpp b/intern/cycles/blender/blender_image.cpp index 3a9d159e461..f27275bd457 100644 --- a/intern/cycles/blender/blender_image.cpp +++ b/intern/cycles/blender/blender_image.cpp @@ -137,9 +137,9 @@ bool BlenderImageLoader::load_pixels(const ImageMetaData &metadata, /* Premultiply, byte images are always straight for Blender. */ unsigned char *cp = (unsigned char *)pixels; for (size_t i = 0; i < num_pixels; i++, cp += channels) { - cp[0] = (cp[0] * cp[3]) >> 8; - cp[1] = (cp[1] * cp[3]) >> 8; - cp[2] = (cp[2] * cp[3]) >> 8; + cp[0] = (cp[0] * cp[3]) / 255; + cp[1] = (cp[1] * cp[3]) / 255; + cp[2] = (cp[2] * cp[3]) / 255; } } } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 635392fb3d4..f5e8db2aee1 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -109,23 +109,23 @@ void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob } Geometry *geom = object->get_geometry(); - geom->set_use_motion_blur(false); - geom->set_motion_steps(0); - uint motion_steps; + int motion_steps = 0; + bool use_motion_blur = false; if (need_motion == Scene::MOTION_BLUR) { motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS); - geom->set_motion_steps(motion_steps); if (motion_steps && object_use_deform_motion(b_parent, b_ob)) { - geom->set_use_motion_blur(true); + use_motion_blur = true; } } else { motion_steps = 3; - geom->set_motion_steps(motion_steps); } + geom->set_use_motion_blur(use_motion_blur); + geom->set_motion_steps(motion_steps); + motion.resize(motion_steps, transform_empty()); if (motion_steps) { diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 3b3a193b3e8..ce399579e25 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -404,8 +404,6 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d) Film *film = scene->film; - vector<Pass> prevpasses = scene->passes; - if (b_v3d) { film->set_display_pass(update_viewport_display_passes(b_v3d, scene->passes)); } @@ -435,11 +433,6 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d) break; } } - - if (!Pass::equals(prevpasses, scene->passes)) { - film->tag_passes_update(scene, prevpasses, false); - film->tag_modified(); - } } /* Render Layer */ @@ -749,10 +742,13 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene, DENOISING_CLEAN_ALL_PASSES); scene->film->set_denoising_prefiltered_pass(denoising.store_passes && denoising.type == DENOISER_NLM); - scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold()); - scene->film->tag_passes_update(scene, passes); - scene->integrator->tag_update(scene, Integrator::UPDATE_ALL); + + if (!Pass::equals(passes, scene->passes)) { + scene->film->tag_passes_update(scene, passes); + scene->film->tag_modified(); + scene->integrator->tag_update(scene, Integrator::UPDATE_ALL); + } return passes; } diff --git a/intern/cycles/blender/blender_viewport.cpp b/intern/cycles/blender/blender_viewport.cpp index 07408fee218..18bdfc74de0 100644 --- a/intern/cycles/blender/blender_viewport.cpp +++ b/intern/cycles/blender/blender_viewport.cpp @@ -40,8 +40,8 @@ BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d) BL::View3DShading shading = b_v3d.shading(); PointerRNA cshading = RNA_pointer_get(&shading.ptr, "cycles"); - /* We only copy the shading parameters if we are in look dev mode. otherwise - * defaults are being used. These defaults mimic normal render settings */ + /* We only copy the shading parameters if we are in look-dev mode. + * Otherwise defaults are being used. These defaults mimic normal render settings. */ if (shading.type() == BL::View3DShading::type_RENDERED) { use_scene_world = shading.use_scene_world_render(); use_scene_lights = shading.use_scene_lights_render(); diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h index 40b2059194b..e25bf5b4660 100644 --- a/intern/cycles/kernel/geom/geom_curve_intersect.h +++ b/intern/cycles/kernel/geom/geom_curve_intersect.h @@ -237,7 +237,7 @@ ccl_device bool curve_intersect_iterative(const float3 ray_dir, return false; /* Rejects NaNs */ } - /* Backface culling. */ + /* Back-face culling. */ const float3 R = normalize(Q - P); const float3 U = dradiusdu * R + dPdu; const float3 V = cross(dPdu, R); @@ -458,10 +458,12 @@ ccl_device_inline bool cylinder_culling_test(const float2 p1, const float2 p2, c return num * num <= r * r * den2; } -/*! Intersects a ray with a quad with backface culling - * enabled. The quad v0,v1,v2,v3 is split into two triangles - * v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two - * triangles gets intersected. */ +/** + * Intersects a ray with a quad with back-face culling + * enabled. The quad v0,v1,v2,v3 is split into two triangles + * v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two + * triangles gets intersected. + */ ccl_device_inline bool ribbon_intersect_quad(const float ray_tfar, const float3 quad_v0, const float3 quad_v1, diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 7970381f338..5abb4750764 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -81,7 +81,7 @@ class Camera : public Node { /* ** Rolling shutter effect. ** */ /* Defines rolling shutter effect type. */ NODE_SOCKET_API(RollingShutterType, rolling_shutter_type) - /* Specifies exposure time of scanlines when using + /* Specifies exposure time of scan-lines when using * rolling shutter effect. */ NODE_SOCKET_API(float, rolling_shutter_duration) diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index ca90af77f6e..19d4a66353d 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -227,66 +227,25 @@ void Session::run_gpu() progress.set_render_start_time(); while (!progress.get_cancel()) { - /* advance to next tile */ - bool no_tiles = !tile_manager.next(); + const bool no_tiles = !run_update_for_next_iteration(); - DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN; if (no_tiles) { - kernel_state = device->get_active_kernel_switch_state(); - } - - if (params.background) { - /* if no work left and in background mode, we can stop immediately */ - if (no_tiles) { + if (params.background) { + /* if no work left and in background mode, we can stop immediately */ progress.set_status("Finished"); break; } } - else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) { - reset_gpu(tile_manager.params, params.samples); + if (run_wait_for_work(no_tiles)) { + continue; } - else { - /* if in interactive mode, and we are either paused or done for now, - * wait for pause condition notify to wake up again */ - thread_scoped_lock pause_lock(pause_mutex); - - if (!pause && !tile_manager.done()) { - /* reset could have happened after no_tiles was set, before this lock. - * in this case we shall not wait for pause condition - */ - } - else if (pause || no_tiles) { - update_status_time(pause, no_tiles); - - while (1) { - scoped_timer pause_timer; - pause_cond.wait(pause_lock); - if (pause) { - progress.add_skip_time(pause_timer, params.background); - } - - update_status_time(pause, no_tiles); - progress.set_update(); - - if (!pause) - break; - } - } - - if (progress.get_cancel()) - break; + if (progress.get_cancel()) { + break; } if (!no_tiles) { - /* update scene */ - scoped_timer update_timer; - if (update_scene()) { - profiler.reset(scene->shaders.size(), scene->objects.size()); - } - progress.add_skip_time(update_timer, params.background); - if (!device->error_message().empty()) progress.set_error(device->error_message()); @@ -729,82 +688,27 @@ void Session::run_cpu() last_update_time = time_dt(); last_display_time = last_update_time; - { - /* reset once to start */ - thread_scoped_lock reset_lock(delayed_reset.mutex); - thread_scoped_lock buffers_lock(buffers_mutex); - thread_scoped_lock display_lock(display_mutex); - - reset_(delayed_reset.params, delayed_reset.samples); - delayed_reset.do_reset = false; - } - while (!progress.get_cancel()) { - /* advance to next tile */ - bool no_tiles = !tile_manager.next(); + const bool no_tiles = !run_update_for_next_iteration(); bool need_copy_to_display_buffer = false; - DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN; if (no_tiles) { - kernel_state = device->get_active_kernel_switch_state(); - } - - if (params.background) { - /* if no work left and in background mode, we can stop immediately */ - if (no_tiles) { + if (params.background) { + /* if no work left and in background mode, we can stop immediately */ progress.set_status("Finished"); break; } } - else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) { - reset_cpu(tile_manager.params, params.samples); + if (run_wait_for_work(no_tiles)) { + continue; } - else { - /* if in interactive mode, and we are either paused or done for now, - * wait for pause condition notify to wake up again */ - thread_scoped_lock pause_lock(pause_mutex); - - if (!pause && delayed_reset.do_reset) { - /* reset once to start */ - thread_scoped_lock reset_lock(delayed_reset.mutex); - thread_scoped_lock buffers_lock(buffers_mutex); - thread_scoped_lock display_lock(display_mutex); - - reset_(delayed_reset.params, delayed_reset.samples); - delayed_reset.do_reset = false; - } - else if (pause || no_tiles) { - update_status_time(pause, no_tiles); - - while (1) { - scoped_timer pause_timer; - pause_cond.wait(pause_lock); - if (pause) { - progress.add_skip_time(pause_timer, params.background); - } - - update_status_time(pause, no_tiles); - progress.set_update(); - - if (!pause) - break; - } - } - - if (progress.get_cancel()) - break; + if (progress.get_cancel()) { + break; } if (!no_tiles) { - /* update scene */ - scoped_timer update_timer; - if (update_scene()) { - profiler.reset(scene->shaders.size(), scene->objects.size()); - } - progress.add_skip_time(update_timer, params.background); - if (!device->error_message().empty()) progress.set_error(device->error_message()); @@ -894,6 +798,63 @@ void Session::run() progress.set_update(); } +bool Session::run_update_for_next_iteration() +{ + thread_scoped_lock scene_lock(scene->mutex); + thread_scoped_lock reset_lock(delayed_reset.mutex); + + if (delayed_reset.do_reset) { + thread_scoped_lock buffers_lock(buffers_mutex); + reset_(delayed_reset.params, delayed_reset.samples); + delayed_reset.do_reset = false; + } + + const bool have_tiles = tile_manager.next(); + + if (have_tiles) { + scoped_timer update_timer; + if (update_scene()) { + profiler.reset(scene->shaders.size(), scene->objects.size()); + } + progress.add_skip_time(update_timer, params.background); + } + + return have_tiles; +} + +bool Session::run_wait_for_work(bool no_tiles) +{ + /* In an offline rendering there is no pause, and no tiles will mean the job is fully done. */ + if (params.background) { + return false; + } + + thread_scoped_lock pause_lock(pause_mutex); + + if (!pause && !no_tiles) { + return false; + } + + update_status_time(pause, no_tiles); + + while (true) { + scoped_timer pause_timer; + pause_cond.wait(pause_lock); + if (pause) { + progress.add_skip_time(pause_timer, params.background); + } + + update_status_time(pause, no_tiles); + progress.set_update(); + + if (!pause) { + break; + } + } + + return no_tiles; +} + bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params) { if (device_use_gl) @@ -1012,8 +973,6 @@ void Session::wait() bool Session::update_scene() { - thread_scoped_lock scene_lock(scene->mutex); - /* update camera if dimensions changed for progressive render. the camera * knows nothing about progressive or cropped rendering, it just gets the * image dimensions passed in */ diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 43ff07e5884..bc3b8366c05 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -178,6 +178,9 @@ class Session { void run(); + bool run_update_for_next_iteration(); + bool run_wait_for_work(bool no_tiles); + void update_status_time(bool show_pause = false, bool show_done = false); void render(bool use_denoise); diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index e98faf522e6..a35c9fffcab 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -293,11 +293,25 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) intern/GHOST_WindowWayland.cpp intern/GHOST_SystemWayland.h + intern/GHOST_WaylandCursorSettings.h intern/GHOST_WindowWayland.h ) pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) - pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) + + pkg_check_modules(wayland-protocols wayland-protocols>=1.15) + if (${wayland-protocols_FOUND}) + pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) + else() + find_path(WAYLAND_PROTOCOLS_DIR + NAMES unstable/xdg-decoration/xdg-decoration-unstable-v1.xml + PATH_SUFFIXES share/wayland-protocols + ) + endif() + + if (NOT EXISTS ${WAYLAND_PROTOCOLS_DIR}) + message(FATAL_ERROR "path to wayland-protocols not found") + endif() # Generate protocols bindings. macro(generate_protocol_bindings NAME PROT_DEF) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 6e22d4ca3a5..db3f9bd561e 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -96,7 +96,7 @@ extern GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consu * \param systemhandle: The handle to the system. * \return The number of milliseconds. */ -extern GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle); +extern uint64_t GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle); /** * Installs a timer. @@ -110,8 +110,8 @@ extern GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle); * \return A timer task (0 if timer task installation failed). */ extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle, - GHOST_TUns64 delay, - GHOST_TUns64 interval, + uint64_t delay, + uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData); @@ -133,7 +133,7 @@ extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle, * \param systemhandle: The handle to the system. * \return The number of displays. */ -extern GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle); +extern uint8_t GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle); /** * Returns the dimensions of the main display on this system. @@ -142,8 +142,8 @@ extern GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle); * \param height: A pointer the height gets put in. */ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, - GHOST_TUns32 *width, - GHOST_TUns32 *height); + uint32_t *width, + uint32_t *height); /** * Returns the dimensions of all displays combine @@ -154,8 +154,8 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, * \param height: A pointer the height gets put in. */ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, - GHOST_TUns32 *width, - GHOST_TUns32 *height); + uint32_t *width, + uint32_t *height); /** * Create a new window. @@ -178,10 +178,10 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle parent_windowhandle, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, bool is_dialog, GHOST_TDrawingContextType type, @@ -360,13 +360,13 @@ extern GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle, * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle, - GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, int hotY, - GHOST_TUns8 canInvertColor); + bool canInvertColor); /** * Returns the visibility state of the cursor. @@ -391,8 +391,8 @@ extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, * \return Indication of success. */ extern GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, - GHOST_TInt32 *x, - GHOST_TInt32 *y); + int32_t *x, + int32_t *y); /** * Updates the location of the cursor (location in screen coordinates). @@ -403,8 +403,8 @@ extern GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, - GHOST_TInt32 x, - GHOST_TInt32 y); + int32_t x, + int32_t y); /** * Grabs the cursor for a modal operation, to keep receiving @@ -467,7 +467,7 @@ extern void GHOST_setNDOFDeadZone(float deadzone); /** * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop */ -extern void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_TInt8 canAccept); +extern void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, bool canAccept); /** * Returns the event type. @@ -481,7 +481,7 @@ extern GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle); * \param eventhandle: The handle to the event. * \return The event generation time. */ -extern GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle); +extern uint64_t GHOST_GetEventTime(GHOST_EventHandle eventhandle); /** * Returns the window this event was generated on, @@ -595,7 +595,7 @@ void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle); * \param width: The new width of the client area of the window. * \return Indication of success. */ -extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width); +extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, uint32_t width); /** * Resizes client rectangle height. @@ -603,7 +603,7 @@ extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOS * \param height: The new height of the client area of the window. * \return Indication of success. */ -extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height); +extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, uint32_t height); /** * Resizes client rectangle. @@ -613,8 +613,8 @@ extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHO * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, - GHOST_TUns32 width, - GHOST_TUns32 height); + uint32_t width, + uint32_t height); /** * Converts a point in screen coordinates to client rectangle coordinates @@ -624,11 +624,8 @@ extern GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, * \param outX: The x-coordinate in the client rectangle. * \param outY: The y-coordinate in the client rectangle. */ -extern void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle, - GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 *outX, - GHOST_TInt32 *outY); +extern void GHOST_ScreenToClient( + GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY); /** * Converts a point in screen coordinates to client rectangle coordinates @@ -638,11 +635,8 @@ extern void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle, * \param outX: The x-coordinate on the screen. * \param outY: The y-coordinate on the screen. */ -extern void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle, - GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 *outX, - GHOST_TInt32 *outY); +extern void GHOST_ClientToScreen( + GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY); /** * Returns the state of the window (normal, minimized, maximized). @@ -667,7 +661,7 @@ extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, - GHOST_TUns8 isUnsavedChanges); + bool isUnsavedChanges); /** * Sets the order of the window (bottom, top). @@ -758,14 +752,14 @@ extern void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI * \param rectanglehandle: The handle to the rectangle. * \return width of the rectangle */ -extern GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle); +extern int32_t GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle); /** * Access to rectangle height. * \param rectanglehandle: The handle to the rectangle. * \return height of the rectangle */ -extern GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle); +extern int32_t GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle); /** * Gets all members of the rectangle. @@ -775,11 +769,8 @@ extern GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehand * \param r: Pointer to return right coordinate in. * \param b: Pointer to return bottom coordinate in. */ -extern void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 *l, - GHOST_TInt32 *t, - GHOST_TInt32 *r, - GHOST_TInt32 *b); +extern void GHOST_GetRectangle( + GHOST_RectangleHandle rectanglehandle, int32_t *l, int32_t *t, int32_t *r, int32_t *b); /** * Sets all members of the rectangle. @@ -789,11 +780,8 @@ extern void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle, * \param r: requested right coordinate of the rectangle. * \param b: requested bottom coordinate of the rectangle. */ -extern void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 l, - GHOST_TInt32 t, - GHOST_TInt32 r, - GHOST_TInt32 b); +extern void GHOST_SetRectangle( + GHOST_RectangleHandle rectanglehandle, int32_t l, int32_t t, int32_t r, int32_t b); /** * Returns whether this rectangle is empty. @@ -818,7 +806,7 @@ extern GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehand * \param rectanglehandle: The handle to the rectangle. * \param i: The amount of offset given to each extreme (negative values shrink the rectangle). */ -extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i); +extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, int32_t i); /** * Does a union of the rectangle given and this rectangle. @@ -835,9 +823,7 @@ extern void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle, * \param x: The x-coordinate of the point. * \param y: The y-coordinate of the point. */ -extern void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 x, - GHOST_TInt32 y); +extern void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, int32_t x, int32_t y); /** * Returns whether the point is inside this rectangle. @@ -848,8 +834,8 @@ extern void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, * \return Success value (true if point is inside). */ extern GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 x, - GHOST_TInt32 y); + int32_t x, + int32_t y); /** * Returns whether the rectangle is inside this rectangle. @@ -868,8 +854,8 @@ extern GHOST_TVisibility GHOST_GetRectangleVisibility( * \param cy: Requested center y-coordinate of the rectangle. */ extern void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 cx, - GHOST_TInt32 cy); + int32_t cx, + int32_t cy); /** * Sets rectangle members. @@ -881,11 +867,8 @@ extern void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, * \param w: requested width of the rectangle. * \param h: requested height of the rectangle. */ -extern void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 cx, - GHOST_TInt32 cy, - GHOST_TInt32 w, - GHOST_TInt32 h); +extern void GHOST_SetRectangleCenter( + GHOST_RectangleHandle rectanglehandle, int32_t cx, int32_t cy, int32_t w, int32_t h); /** * Clips a rectangle. @@ -903,14 +886,14 @@ extern GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle, * \param selection: Boolean to return the selection instead, X11 only feature. * \return clipboard data */ -extern GHOST_TUns8 *GHOST_getClipboard(int selection); +extern char *GHOST_getClipboard(bool selection); /** * Put data to the Clipboard * \param buffer: the string buffer to set. * \param selection: Set the selection instead, X11 only feature. */ -extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection); +extern void GHOST_putClipboard(const char *buffer, bool selection); /** * Toggles console @@ -942,7 +925,7 @@ extern float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle); /** * Returns the suggested DPI for this window. */ -extern GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle); +extern uint16_t GHOST_GetDPIHint(GHOST_WindowHandle windowhandle); /** * Enable IME attached to the given window, i.e. allows user-input @@ -956,12 +939,8 @@ extern GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle); * - true: Start a new composition. * - false: Move the IME windows to the given position without finishing it. */ -extern void GHOST_BeginIME(GHOST_WindowHandle windowhandle, - GHOST_TInt32 x, - GHOST_TInt32 y, - GHOST_TInt32 w, - GHOST_TInt32 h, - int complete); +extern void GHOST_BeginIME( + GHOST_WindowHandle windowhandle, int32_t x, int32_t y, int32_t w, int32_t h, bool complete); /** * Disable the IME attached to the given window, i.e. prohibits any user-input * events from being dispatched to the IME. @@ -1076,7 +1055,7 @@ void GHOST_XrDestroyActionSet(GHOST_XrContextHandle xr_context, const char *acti */ int GHOST_XrCreateActions(GHOST_XrContextHandle xr_context, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionInfo *infos); /** @@ -1084,7 +1063,7 @@ int GHOST_XrCreateActions(GHOST_XrContextHandle xr_context, */ void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_context, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const char *const *action_names); /** @@ -1092,7 +1071,7 @@ void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_context, */ int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_context, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionSpaceInfo *infos); /** @@ -1100,7 +1079,7 @@ int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_context, */ void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_context, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionSpaceInfo *infos); /** @@ -1108,7 +1087,7 @@ void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_context, */ int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_context, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionProfileInfo *infos); /** @@ -1116,7 +1095,7 @@ int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_context, */ void GHOST_XrDestroyActionBindings(GHOST_XrContextHandle xr_context, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionProfileInfo *infos); /** @@ -1138,7 +1117,7 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_context, const char *action_set int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context, const char *action_set_name, const char *action_name, - const GHOST_TInt64 *duration, + const int64_t *duration, const float *frequency, const float *amplitude); diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h index c63064c123a..bcccd536ebd 100644 --- a/intern/ghost/GHOST_IEvent.h +++ b/intern/ghost/GHOST_IEvent.h @@ -58,7 +58,7 @@ class GHOST_IEvent { * Returns the time this event was generated. * \return The event generation time. */ - virtual GHOST_TUns64 getTime() = 0; + virtual uint64_t getTime() = 0; /** * Returns the window this event was generated on, diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 81b54cf5a0d..4c395f720df 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -177,7 +177,7 @@ class GHOST_ISystem { * Based on ANSI clock() routine. * \return The number of milliseconds. */ - virtual GHOST_TUns64 getMilliSeconds() const = 0; + virtual uint64_t getMilliSeconds() const = 0; /** * Installs a timer. @@ -189,8 +189,8 @@ class GHOST_ISystem { * \param userData: Placeholder for user data. * \return A timer task (0 if timer task installation failed). */ - virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay, - GHOST_TUns64 interval, + virtual GHOST_ITimerTask *installTimer(uint64_t delay, + uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = NULL) = 0; @@ -209,19 +209,19 @@ class GHOST_ISystem { * Returns the number of displays on this system. * \return The number of displays. */ - virtual GHOST_TUns8 getNumDisplays() const = 0; + virtual uint8_t getNumDisplays() const = 0; /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ - virtual void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const = 0; + virtual void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const = 0; /** * Returns the combine dimensions of all monitors. * \return The dimension of the workspace. */ - virtual void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const = 0; + virtual void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const = 0; /** * Create a new window. @@ -242,10 +242,10 @@ class GHOST_ISystem { * \return The new window (or 0 if creation failed). */ virtual GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -365,7 +365,7 @@ class GHOST_ISystem { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const = 0; + virtual GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const = 0; /** * Updates the location of the cursor (location in screen coordinates). @@ -374,7 +374,7 @@ class GHOST_ISystem { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) = 0; + virtual GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) = 0; /*************************************************************************************** * Access to mouse button and keyboard states. @@ -431,12 +431,12 @@ class GHOST_ISystem { * \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer * */ - virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; + virtual char *getClipboard(bool selection) const = 0; /** * Put data to the Clipboard */ - virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; + virtual void putClipboard(const char *buffer, bool selection) const = 0; /*************************************************************************************** * System Message Box. diff --git a/intern/ghost/GHOST_ISystemPaths.h b/intern/ghost/GHOST_ISystemPaths.h index 74285b7e0ce..8298f4b78e2 100644 --- a/intern/ghost/GHOST_ISystemPaths.h +++ b/intern/ghost/GHOST_ISystemPaths.h @@ -68,26 +68,26 @@ class GHOST_ISystemPaths { * "unpack and run" path, then look for properly installed path, including versioning. * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). */ - virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0; + virtual const char *getSystemDir(int version, const char *versionstr) const = 0; /** * Determine the base dir in which user configuration is stored, including versioning. * If needed, it will create the base directory. * \return Unsigned char string pointing to user dir (eg ~/.blender/). */ - virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0; + virtual const char *getUserDir(int version, const char *versionstr) const = 0; /** * Determine a special ("well known") and easy to reach user directory. * \return Unsigned char string pointing to user dir (eg `~/Documents/`). */ - virtual const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const = 0; + virtual const char *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const = 0; /** * Determine the directory of the current binary * \return Unsigned char string pointing to the binary dir */ - virtual const GHOST_TUns8 *getBinaryDir() const = 0; + virtual const char *getBinaryDir() const = 0; /** * Add the file to the operating system most recently used files diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 1650b230812..f870791b345 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -108,20 +108,20 @@ class GHOST_IWindow { * Resizes client rectangle width. * \param width: The new width of the client area of the window. */ - virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0; + virtual GHOST_TSuccess setClientWidth(uint32_t width) = 0; /** * Resizes client rectangle height. * \param height: The new height of the client area of the window. */ - virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0; + virtual GHOST_TSuccess setClientHeight(uint32_t height) = 0; /** * Resizes client rectangle. * \param width: The new width of the client area of the window. * \param height: The new height of the client area of the window. */ - virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0; + virtual GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) = 0; /** * Converts a point in screen coordinates to client rectangle coordinates @@ -130,10 +130,7 @@ class GHOST_IWindow { * \param outX: The x-coordinate in the client rectangle. * \param outY: The y-coordinate in the client rectangle. */ - virtual void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const = 0; + virtual void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const = 0; /** * Converts a point in screen coordinates to client rectangle coordinates @@ -142,10 +139,7 @@ class GHOST_IWindow { * \param outX: The x-coordinate on the screen. * \param outY: The y-coordinate on the screen. */ - virtual void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const = 0; + virtual void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const = 0; /** * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop @@ -290,8 +284,8 @@ class GHOST_IWindow { * \param hotY: The Y coordinate of the cursor hot-spot. * \return Indication of success. */ - virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + virtual GHOST_TSuccess setCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -319,7 +313,7 @@ class GHOST_IWindow { virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/, GHOST_TAxisFlag /*wrap_axis*/, GHOST_Rect * /*bounds*/, - GHOST_TInt32 /*mouse_ungrab_xy*/[2]) + int32_t /*mouse_ungrab_xy*/[2]) { return GHOST_kSuccess; } @@ -334,7 +328,7 @@ class GHOST_IWindow { * Returns the recommended DPI for this window. * \return The recommended DPI for this window. */ - virtual GHOST_TUns16 getDPIHint() = 0; + virtual uint16_t getDPIHint() = 0; #ifdef WITH_INPUT_IME /** @@ -348,8 +342,7 @@ class GHOST_IWindow { * - true: Start a new composition * - false: Move the IME windows to the given position without finishing it. */ - virtual void beginIME( - GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) = 0; + virtual void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed) = 0; /** * Disable the IME attached to the given window, i.e. prohibits any user-input diff --git a/intern/ghost/GHOST_Path-api.h b/intern/ghost/GHOST_Path-api.h index 36ea70838ca..81df2e607eb 100644 --- a/intern/ghost/GHOST_Path-api.h +++ b/intern/ghost/GHOST_Path-api.h @@ -48,25 +48,25 @@ extern GHOST_TSuccess GHOST_DisposeSystemPaths(void); * "unpack and run" path, then look for properly installed path, including versioning. * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). */ -extern const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr); +extern const char *GHOST_getSystemDir(int version, const char *versionstr); /** * Determine the base dir in which user configuration is stored, including versioning. * \return Unsigned char string pointing to user dir (eg ~). */ -extern const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr); +extern const char *GHOST_getUserDir(int version, const char *versionstr); /** * Determine a special ("well known") and easy to reach user directory. * \return Unsigned char string pointing to user dir (eg `~/Documents/`). */ -extern const GHOST_TUns8 *GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type); +extern const char *GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type); /** * Determine the dir in which the binary file is found. * \return Unsigned char string pointing to binary dir (eg ~/usr/local/bin/). */ -extern const GHOST_TUns8 *GHOST_getBinaryDir(void); +extern const char *GHOST_getBinaryDir(void); /** * Add the file to the operating system most recently used files diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h index dae2a2a8cbb..1c67ca3d2e0 100644 --- a/intern/ghost/GHOST_Rect.h +++ b/intern/ghost/GHOST_Rect.h @@ -42,7 +42,7 @@ class GHOST_Rect { * \param r: requested right coordinate of the rectangle. * \param b: requested bottom coordinate of the rectangle. */ - GHOST_Rect(GHOST_TInt32 l = 0, GHOST_TInt32 t = 0, GHOST_TInt32 r = 0, GHOST_TInt32 b = 0) + GHOST_Rect(int32_t l = 0, int32_t t = 0, int32_t r = 0, int32_t b = 0) : m_l(l), m_t(t), m_r(r), m_b(b) { } @@ -58,13 +58,13 @@ class GHOST_Rect { * Access to rectangle width. * \return width of the rectangle. */ - virtual inline GHOST_TInt32 getWidth() const; + virtual inline int32_t getWidth() const; /** * Access to rectangle height. * \return height of the rectangle. */ - virtual inline GHOST_TInt32 getHeight() const; + virtual inline int32_t getHeight() const; /** * Sets all members of the rectangle. @@ -73,7 +73,7 @@ class GHOST_Rect { * \param r: requested right coordinate of the rectangle. * \param b: requested bottom coordinate of the rectangle. */ - virtual inline void set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b); + virtual inline void set(int32_t l, int32_t t, int32_t r, int32_t b); /** * Returns whether this rectangle is empty. @@ -95,7 +95,7 @@ class GHOST_Rect { * The method avoids negative insets making the rectangle invalid * \param i: The amount of offset given to each extreme (negative values shrink the rectangle). */ - virtual void inset(GHOST_TInt32 i); + virtual void inset(int32_t i); /** * Does a union of the rectangle given and this rectangle. @@ -109,17 +109,14 @@ class GHOST_Rect { * \param x: The x-coordinate of the point. * \param y: The y-coordinate of the point. */ - virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y); + virtual inline void unionPoint(int32_t x, int32_t y); /** * Grows the rectangle to included a point. * \param x: The x-coordinate of the point. * \param y: The y-coordinate of the point. */ - virtual inline void wrapPoint(GHOST_TInt32 &x, - GHOST_TInt32 &y, - GHOST_TInt32 ofs, - GHOST_TAxisFlag axis); + virtual inline void wrapPoint(int32_t &x, int32_t &y, int32_t ofs, GHOST_TAxisFlag axis); /** * Returns whether the point is inside this rectangle. @@ -128,7 +125,7 @@ class GHOST_Rect { * \param y: y-coordinate of point to test. * \return boolean value (true if point is inside). */ - virtual inline bool isInside(GHOST_TInt32 x, GHOST_TInt32 y) const; + virtual inline bool isInside(int32_t x, int32_t y) const; /** * Returns whether the rectangle is inside this rectangle. @@ -143,7 +140,7 @@ class GHOST_Rect { * \param cx: requested center x-coordinate of the rectangle. * \param cy: requested center y-coordinate of the rectangle. */ - virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy); + virtual void setCenter(int32_t cx, int32_t cy); /** * Sets rectangle members. @@ -154,7 +151,7 @@ class GHOST_Rect { * \param w: requested width of the rectangle. * \param h: requested height of the rectangle. */ - virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h); + virtual void setCenter(int32_t cx, int32_t cy, int32_t w, int32_t h); /** * Clips a rectangle. @@ -166,30 +163,30 @@ class GHOST_Rect { virtual bool clip(GHOST_Rect &r) const; /** Left coordinate of the rectangle */ - GHOST_TInt32 m_l; + int32_t m_l; /** Top coordinate of the rectangle */ - GHOST_TInt32 m_t; + int32_t m_t; /** Right coordinate of the rectangle */ - GHOST_TInt32 m_r; + int32_t m_r; /** Bottom coordinate of the rectangle */ - GHOST_TInt32 m_b; + int32_t m_b; #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Rect") #endif }; -inline GHOST_TInt32 GHOST_Rect::getWidth() const +inline int32_t GHOST_Rect::getWidth() const { return m_r - m_l; } -inline GHOST_TInt32 GHOST_Rect::getHeight() const +inline int32_t GHOST_Rect::getHeight() const { return m_b - m_t; } -inline void GHOST_Rect::set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b) +inline void GHOST_Rect::set(int32_t l, int32_t t, int32_t r, int32_t b) { m_l = l; m_t = t; @@ -219,7 +216,7 @@ inline void GHOST_Rect::unionRect(const GHOST_Rect &r) m_b = r.m_b; } -inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y) +inline void GHOST_Rect::unionPoint(int32_t x, int32_t y) { if (x < m_l) m_l = x; @@ -231,13 +228,10 @@ inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y) m_b = y; } -inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, - GHOST_TInt32 &y, - GHOST_TInt32 ofs, - GHOST_TAxisFlag axis) +inline void GHOST_Rect::wrapPoint(int32_t &x, int32_t &y, int32_t ofs, GHOST_TAxisFlag axis) { - GHOST_TInt32 w = getWidth(); - GHOST_TInt32 h = getHeight(); + int32_t w = getWidth(); + int32_t h = getHeight(); /* highly unlikely but avoid eternal loop */ if (w - ofs * 2 <= 0 || h - ofs * 2 <= 0) { @@ -258,7 +252,7 @@ inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, } } -inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const +inline bool GHOST_Rect::isInside(int32_t x, int32_t y) const { return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b); } diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 7efbd00c2eb..ff93de4f203 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -23,6 +23,8 @@ #pragma once +#include <stdint.h> + #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" #endif @@ -56,13 +58,6 @@ GHOST_DECLARE_HANDLE(GHOST_EventConsumerHandle); GHOST_DECLARE_HANDLE(GHOST_ContextHandle); GHOST_DECLARE_HANDLE(GHOST_XrContextHandle); -typedef char GHOST_TInt8; -typedef unsigned char GHOST_TUns8; -typedef short GHOST_TInt16; -typedef unsigned short GHOST_TUns16; -typedef int GHOST_TInt32; -typedef unsigned int GHOST_TUns32; - typedef struct { int flags; } GHOST_GLSettings; @@ -78,14 +73,6 @@ typedef enum GHOST_DialogOptions { GHOST_DialogError = (1 << 1), } GHOST_DialogOptions; -#ifdef _MSC_VER -typedef __int64 GHOST_TInt64; -typedef unsigned __int64 GHOST_TUns64; -#else -typedef long long GHOST_TInt64; -typedef unsigned long long GHOST_TUns64; -#endif - typedef void *GHOST_TUserDataPtr; typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess; @@ -436,9 +423,9 @@ typedef void *GHOST_TEventDataPtr; typedef struct { /** The x-coordinate of the cursor position. */ - GHOST_TInt32 x; + int32_t x; /** The y-coordinate of the cursor position. */ - GHOST_TInt32 y; + int32_t y; /** Associated tablet data. */ GHOST_TabletData tablet; } GHOST_TEventCursorData; @@ -452,7 +439,7 @@ typedef struct { typedef struct { /** Displacement of a mouse wheel. */ - GHOST_TInt32 z; + int32_t z; } GHOST_TEventWheelData; typedef enum { @@ -468,13 +455,13 @@ typedef struct { /** The event subtype */ GHOST_TTrackpadEventSubTypes subtype; /** The x-location of the trackpad event */ - GHOST_TInt32 x; + int32_t x; /** The y-location of the trackpad event */ - GHOST_TInt32 y; + int32_t y; /** The x-delta or value of the trackpad event */ - GHOST_TInt32 deltaX; + int32_t deltaX; /** The y-delta (currently only for scroll subtype) of the trackpad event */ - GHOST_TInt32 deltaY; + int32_t deltaY; /** The delta is inverted from the device due to system preferences. */ char isDirectionInverted; } GHOST_TEventTrackpadData; @@ -488,9 +475,9 @@ typedef enum { typedef struct { /** The x-coordinate of the cursor position. */ - GHOST_TInt32 x; + int32_t x; /** The y-coordinate of the cursor position. */ - GHOST_TInt32 y; + int32_t y; /** The dropped item type */ GHOST_TDragnDropTypes dataType; /** The "dropped content" */ @@ -515,7 +502,7 @@ typedef struct { typedef struct { int count; - GHOST_TUns8 **strings; + uint8_t **strings; } GHOST_TStringArray; typedef enum { @@ -587,13 +574,13 @@ typedef enum { typedef struct { /** Number of pixels on a line. */ - GHOST_TUns32 xPixels; + uint32_t xPixels; /** Number of lines. */ - GHOST_TUns32 yPixels; + uint32_t yPixels; /** Number of bits per pixel. */ - GHOST_TUns32 bpp; + uint32_t bpp; /** Refresh rate (in Hertz). */ - GHOST_TUns32 frequency; + uint32_t frequency; } GHOST_DisplaySetting; #ifdef _WIN32 @@ -613,10 +600,10 @@ typedef int GHOST_TEmbedderWindowID; */ #ifdef __cplusplus class GHOST_ITimerTask; -typedef void (*GHOST_TimerProcPtr)(GHOST_ITimerTask *task, GHOST_TUns64 time); +typedef void (*GHOST_TimerProcPtr)(GHOST_ITimerTask *task, uint64_t time); #else struct GHOST_TimerTaskHandle__; -typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_TUns64 time); +typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, uint64_t time); #endif #ifdef WITH_XR_OPENXR @@ -724,7 +711,7 @@ typedef enum GHOST_XrActionType { typedef struct GHOST_XrActionInfo { const char *name; GHOST_XrActionType type; - GHOST_TUns32 count_subaction_paths; + uint32_t count_subaction_paths; const char **subaction_paths; /** States for each subaction path. */ void *states; @@ -735,7 +722,7 @@ typedef struct GHOST_XrActionInfo { typedef struct GHOST_XrActionSpaceInfo { const char *action_name; - GHOST_TUns32 count_subaction_paths; + uint32_t count_subaction_paths; const char **subaction_paths; /** Poses for each subaction path. */ const GHOST_XrPose *poses; @@ -743,14 +730,14 @@ typedef struct GHOST_XrActionSpaceInfo { typedef struct GHOST_XrActionBindingInfo { const char *action_name; - GHOST_TUns32 count_interaction_paths; + uint32_t count_interaction_paths; /** Interaction path: User (sub-action) path + component path. */ const char **interaction_paths; } GHOST_XrActionBindingInfo; typedef struct GHOST_XrActionProfileInfo { const char *profile_path; - GHOST_TUns32 count_bindings; + uint32_t count_bindings; const GHOST_XrActionBindingInfo *bindings; } GHOST_XrActionProfileInfo; diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h index e77bab4f2ec..b216d9f2839 100644 --- a/intern/ghost/intern/GHOST_Buttons.h +++ b/intern/ghost/intern/GHOST_Buttons.h @@ -57,7 +57,7 @@ struct GHOST_Buttons { */ void clear(); - GHOST_TUns8 m_ButtonLeft : 1; - GHOST_TUns8 m_ButtonMiddle : 1; - GHOST_TUns8 m_ButtonRight : 1; + uint8_t m_ButtonLeft : 1; + uint8_t m_ButtonMiddle : 1; + uint8_t m_ButtonRight : 1; }; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 955f35274ea..cb409595e50 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -84,7 +84,7 @@ GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhand return GHOST_kSuccess; } -GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle) +uint64_t GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; @@ -92,8 +92,8 @@ GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle) } GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle, - GHOST_TUns64 delay, - GHOST_TUns64 interval, + uint64_t delay, + uint64_t interval, GHOST_TimerProcPtr timerproc, GHOST_TUserDataPtr userdata) { @@ -111,7 +111,7 @@ GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle, return system->removeTimer(timertask); } -GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle) +uint8_t GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; @@ -119,8 +119,8 @@ GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle) } void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, - GHOST_TUns32 *width, - GHOST_TUns32 *height) + uint32_t *width, + uint32_t *height) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; @@ -128,8 +128,8 @@ void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, } void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, - GHOST_TUns32 *width, - GHOST_TUns32 *height) + uint32_t *width, + uint32_t *height) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; @@ -156,10 +156,10 @@ GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle, GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle parent_windowhandle, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, bool is_dialog, GHOST_TDrawingContextType type, @@ -317,13 +317,13 @@ GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle, } GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle, - GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, int hotY, - GHOST_TUns8 canInvertColor) + bool canInvertColor) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; @@ -344,18 +344,14 @@ GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int vi return window->setCursorVisibility(visible ? true : false); } -GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, - GHOST_TInt32 *x, - GHOST_TInt32 *y) +GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, int32_t *x, int32_t *y) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; return system->getCursorPosition(*x, *y); } -GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, - GHOST_TInt32 x, - GHOST_TInt32 y) +GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, int32_t x, int32_t y) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; @@ -370,7 +366,7 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; GHOST_Rect bounds_rect; - GHOST_TInt32 mouse_xy[2]; + int32_t mouse_xy[2]; if (bounds) { bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]); @@ -420,7 +416,7 @@ void GHOST_setNDOFDeadZone(float deadzone) } #endif -void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_TInt8 canAccept) +void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, bool canAccept) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; @@ -434,7 +430,7 @@ GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle) return event->getType(); } -GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle) +uint64_t GHOST_GetEventTime(GHOST_EventHandle eventhandle) { GHOST_IEvent *event = (GHOST_IEvent *)eventhandle; @@ -555,14 +551,14 @@ void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle) delete (GHOST_Rect *)rectanglehandle; } -GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width) +GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, uint32_t width) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; return window->setClientWidth(width); } -GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height) +GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, uint32_t height) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; @@ -570,30 +566,24 @@ GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns } GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, - GHOST_TUns32 width, - GHOST_TUns32 height) + uint32_t width, + uint32_t height) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; return window->setClientSize(width, height); } -void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle, - GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 *outX, - GHOST_TInt32 *outY) +void GHOST_ScreenToClient( + GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; window->screenToClient(inX, inY, *outX, *outY); } -void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle, - GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 *outX, - GHOST_TInt32 *outY) +void GHOST_ClientToScreen( + GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; @@ -614,8 +604,7 @@ GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWind return window->setState(state); } -GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, - GHOST_TUns8 isUnsavedChanges) +GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, bool isUnsavedChanges) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; @@ -703,21 +692,18 @@ void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api) system->setTabletAPI(api); } -GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle) +int32_t GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle) { return ((GHOST_Rect *)rectanglehandle)->getWidth(); } -GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle) +int32_t GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle) { return ((GHOST_Rect *)rectanglehandle)->getHeight(); } -void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 *l, - GHOST_TInt32 *t, - GHOST_TInt32 *r, - GHOST_TInt32 *b) +void GHOST_GetRectangle( + GHOST_RectangleHandle rectanglehandle, int32_t *l, int32_t *t, int32_t *r, int32_t *b) { GHOST_Rect *rect = (GHOST_Rect *)rectanglehandle; @@ -727,11 +713,8 @@ void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle, *b = rect->m_b; } -void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 l, - GHOST_TInt32 t, - GHOST_TInt32 r, - GHOST_TInt32 b) +void GHOST_SetRectangle( + GHOST_RectangleHandle rectanglehandle, int32_t l, int32_t t, int32_t r, int32_t b) { ((GHOST_Rect *)rectanglehandle)->set(l, t, r, b); } @@ -756,7 +739,7 @@ GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle) return result; } -void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i) +void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, int32_t i) { ((GHOST_Rect *)rectanglehandle)->inset(i); } @@ -767,16 +750,12 @@ void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle, ((GHOST_Rect *)rectanglehandle)->unionRect(*(GHOST_Rect *)anotherrectanglehandle); } -void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 x, - GHOST_TInt32 y) +void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, int32_t x, int32_t y) { ((GHOST_Rect *)rectanglehandle)->unionPoint(x, y); } -GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 x, - GHOST_TInt32 y) +GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle, int32_t x, int32_t y) { GHOST_TSuccess result = GHOST_kFailure; @@ -796,18 +775,13 @@ GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectangleha return visible; } -void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 cx, - GHOST_TInt32 cy) +void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, int32_t cx, int32_t cy) { ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy); } -void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle, - GHOST_TInt32 cx, - GHOST_TInt32 cy, - GHOST_TInt32 w, - GHOST_TInt32 h) +void GHOST_SetRectangleCenter( + GHOST_RectangleHandle rectanglehandle, int32_t cx, int32_t cy, int32_t w, int32_t h) { ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy, w, h); } @@ -823,13 +797,13 @@ GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle, return result; } -GHOST_TUns8 *GHOST_getClipboard(int selection) +char *GHOST_getClipboard(bool selection) { GHOST_ISystem *system = GHOST_ISystem::getSystem(); return system->getClipboard(selection); } -void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection) +void GHOST_putClipboard(const char *buffer, bool selection) { GHOST_ISystem *system = GHOST_ISystem::getSystem(); system->putClipboard(buffer, selection); @@ -861,7 +835,7 @@ float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle) return 1.0f; } -GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle) +uint16_t GHOST_GetDPIHint(GHOST_WindowHandle windowhandle) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; return window->getDPIHint(); @@ -869,12 +843,8 @@ GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle) #ifdef WITH_INPUT_IME -void GHOST_BeginIME(GHOST_WindowHandle windowhandle, - GHOST_TInt32 x, - GHOST_TInt32 y, - GHOST_TInt32 w, - GHOST_TInt32 h, - int complete) +void GHOST_BeginIME( + GHOST_WindowHandle windowhandle, int32_t x, int32_t y, int32_t w, int32_t h, bool complete) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; window->beginIME(x, y, w, h, complete); @@ -972,7 +942,7 @@ void GHOST_XrDestroyActionSet(GHOST_XrContextHandle xr_contexthandle, const char int GHOST_XrCreateActions(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionInfo *infos) { GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle; @@ -983,7 +953,7 @@ int GHOST_XrCreateActions(GHOST_XrContextHandle xr_contexthandle, void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const char *const *action_names) { GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle; @@ -993,7 +963,7 @@ void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_contexthandle, int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionSpaceInfo *infos) { GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle; @@ -1005,7 +975,7 @@ int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_contexthandle, void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionSpaceInfo *infos) { GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle; @@ -1015,7 +985,7 @@ void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_contexthandle, int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionProfileInfo *infos) { GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle; @@ -1027,7 +997,7 @@ int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_contexthandle, void GHOST_XrDestroyActionBindings(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, - GHOST_TUns32 count, + uint32_t count, const GHOST_XrActionProfileInfo *infos) { GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle; @@ -1054,7 +1024,7 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_contexthandle, const char *acti int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name, const char *action_name, - const GHOST_TInt64 *duration, + const int64_t *duration, const float *frequency, const float *amplitude) { diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp index d8321bb1732..fe12a76753d 100644 --- a/intern/ghost/intern/GHOST_DisplayManager.cpp +++ b/intern/ghost/intern/GHOST_DisplayManager.cpp @@ -49,20 +49,20 @@ GHOST_TSuccess GHOST_DisplayManager::initialize(void) return success; } -GHOST_TSuccess GHOST_DisplayManager::getNumDisplays(GHOST_TUns8 & /*numDisplays*/) const +GHOST_TSuccess GHOST_DisplayManager::getNumDisplays(uint8_t & /*numDisplays*/) const { // Don't know if we have a display... return GHOST_kFailure; } -GHOST_TSuccess GHOST_DisplayManager::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32 &numSettings) const +GHOST_TSuccess GHOST_DisplayManager::getNumDisplaySettings(uint8_t display, + int32_t &numSettings) const { GHOST_TSuccess success; GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false"); - GHOST_TUns8 numDisplays; + uint8_t numDisplays; success = getNumDisplays(numDisplays); if (success == GHOST_kSuccess) { if (display < numDisplays) { @@ -75,18 +75,18 @@ GHOST_TSuccess GHOST_DisplayManager::getNumDisplaySettings(GHOST_TUns8 display, return success; } -GHOST_TSuccess GHOST_DisplayManager::getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, +GHOST_TSuccess GHOST_DisplayManager::getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const { GHOST_TSuccess success; GHOST_ASSERT(m_settingsInitialized, "GHOST_DisplayManager::getNumDisplaySettings(): m_settingsInitialized=false"); - GHOST_TUns8 numDisplays; + uint8_t numDisplays; success = getNumDisplays(numDisplays); if (success == GHOST_kSuccess) { - if (display < numDisplays && ((GHOST_TUns8)index < m_settings[display].size())) { + if (display < numDisplays && ((uint8_t)index < m_settings[display].size())) { setting = m_settings[display][index]; } else { @@ -97,18 +97,18 @@ GHOST_TSuccess GHOST_DisplayManager::getDisplaySetting(GHOST_TUns8 display, } GHOST_TSuccess GHOST_DisplayManager::getCurrentDisplaySetting( - GHOST_TUns8 /*display*/, GHOST_DisplaySetting & /*setting*/) const + uint8_t /*display*/, GHOST_DisplaySetting & /*setting*/) const { return GHOST_kFailure; } GHOST_TSuccess GHOST_DisplayManager::setCurrentDisplaySetting( - GHOST_TUns8 /*display*/, const GHOST_DisplaySetting & /*setting*/) + uint8_t /*display*/, const GHOST_DisplaySetting & /*setting*/) { return GHOST_kFailure; } -GHOST_TSuccess GHOST_DisplayManager::findMatch(GHOST_TUns8 display, +GHOST_TSuccess GHOST_DisplayManager::findMatch(uint8_t display, const GHOST_DisplaySetting &setting, GHOST_DisplaySetting &match) const { @@ -157,17 +157,16 @@ GHOST_TSuccess GHOST_DisplayManager::findMatch(GHOST_TUns8 display, GHOST_TSuccess GHOST_DisplayManager::initializeSettings(void) { - GHOST_TUns8 numDisplays; + uint8_t numDisplays; GHOST_TSuccess success = getNumDisplays(numDisplays); if (success == GHOST_kSuccess) { - for (GHOST_TUns8 display = 0; (display < numDisplays) && (success == GHOST_kSuccess); - display++) { + for (uint8_t display = 0; (display < numDisplays) && (success == GHOST_kSuccess); display++) { GHOST_DisplaySettings displaySettings; m_settings.push_back(displaySettings); - GHOST_TInt32 numSettings; + int32_t numSettings; success = getNumDisplaySettings(display, numSettings); if (success == GHOST_kSuccess) { - GHOST_TInt32 index; + int32_t index; GHOST_DisplaySetting setting; for (index = 0; (index < numSettings) && (success == GHOST_kSuccess); index++) { success = getDisplaySetting(display, index, setting); diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h index 26bc687a179..609dfa72dc6 100644 --- a/intern/ghost/intern/GHOST_DisplayManager.h +++ b/intern/ghost/intern/GHOST_DisplayManager.h @@ -55,7 +55,7 @@ class GHOST_DisplayManager { * \param numDisplays: The number of displays on this system. * \return Indication of success. */ - virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; + virtual GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const; /** * Returns the number of display settings for this display device. @@ -63,8 +63,7 @@ class GHOST_DisplayManager { * \param numSettings: The number of settings of the display device with this index. * \return Indication of success. */ - virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32 &numSettings) const; + virtual GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const; /** * Returns the current setting for this display device. @@ -73,8 +72,8 @@ class GHOST_DisplayManager { * \param setting: The setting of the display device with this index. * \return Indication of success. */ - virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, + virtual GHOST_TSuccess getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const; /** @@ -83,7 +82,7 @@ class GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, + virtual GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const; /** @@ -94,7 +93,7 @@ class GHOST_DisplayManager { * \param setting: The setting of the display device to be matched and activated. * \return Indication of success. */ - virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, + virtual GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting); protected: @@ -107,7 +106,7 @@ class GHOST_DisplayManager { * \param match: The optimal display setting. * \return Indication of success. */ - GHOST_TSuccess findMatch(GHOST_TUns8 display, + GHOST_TSuccess findMatch(uint8_t display, const GHOST_DisplaySetting &setting, GHOST_DisplaySetting &match) const; diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h index 745ad457796..cea124a601d 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h @@ -46,7 +46,7 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { * \param numDisplays: The number of displays on this system. * \return Indication of success. */ - GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; + GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const; /** * Returns the number of display settings for this display device. @@ -54,7 +54,7 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { * \param numSetting: The number of settings of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const; + GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const; /** * Returns the current setting for this display device. @@ -63,8 +63,8 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { * \param setting: The setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, + GHOST_TSuccess getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const; /** @@ -73,8 +73,7 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting &setting) const; + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const; /** * Changes the current setting for this display device. @@ -82,8 +81,7 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, - const GHOST_DisplaySetting &setting); + GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting); protected: // Do not cache values as OS X supports screen hot plug diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm index d899bb1c3c7..b983f5a9a4d 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm @@ -29,26 +29,26 @@ GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void) { } -GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8 &numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(uint8_t &numDisplays) const { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - numDisplays = (GHOST_TUns8)[[NSScreen screens] count]; + numDisplays = (uint8_t)[[NSScreen screens] count]; [pool drain]; return GHOST_kSuccess; } -GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32 &numSettings) const +GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(uint8_t display, + int32_t &numSettings) const { - numSettings = (GHOST_TInt32)3; // Width, Height, BitsPerPixel + numSettings = (int32_t)3; // Width, Height, BitsPerPixel return GHOST_kSuccess; } -GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, +GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const { NSScreen *askedDisplay; @@ -86,7 +86,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, } GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting( - GHOST_TUns8 display, GHOST_DisplaySetting &setting) const + uint8_t display, GHOST_DisplaySetting &setting) const { NSScreen *askedDisplay; @@ -127,7 +127,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting( } GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting( - GHOST_TUns8 display, const GHOST_DisplaySetting &setting) + uint8_t display, const GHOST_DisplaySetting &setting) { GHOST_ASSERT( (display == kMainDisplay), diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h index 4ca06faec12..6b9e9a5a30e 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h @@ -31,25 +31,25 @@ class GHOST_DisplayManagerNULL : public GHOST_DisplayManager { GHOST_DisplayManagerNULL(GHOST_SystemNULL *system) : GHOST_DisplayManager(), m_system(system) { /* nop */ } - GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const + GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const { return GHOST_kFailure; } - GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const + GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const { return GHOST_kFailure; } - GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, + GHOST_TSuccess getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const { return GHOST_kFailure; } - GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting &setting) const + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const { - return getDisplaySetting(display, GHOST_TInt32(0), setting); + return getDisplaySetting(display, int32_t(0), setting); } - GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting &setting) + GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting) { return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp index 11134ad1054..18adf948e3b 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp @@ -33,14 +33,14 @@ GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system) memset(&m_mode, 0, sizeof(m_mode)); } -GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8 &numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplays(uint8_t &numDisplays) const { numDisplays = SDL_GetNumVideoDisplays(); return GHOST_kSuccess; } -GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32 &numSettings) const +GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(uint8_t display, + int32_t &numSettings) const { GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); @@ -66,8 +66,8 @@ static void ghost_mode_to_sdl(const GHOST_DisplaySetting &setting, SDL_DisplayMo mode->refresh_rate = setting.frequency; } -GHOST_TSuccess GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, +GHOST_TSuccess GHOST_DisplayManagerSDL::getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const { GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); @@ -81,7 +81,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, } GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplaySetting( - GHOST_TUns8 display, GHOST_DisplaySetting &setting) const + uint8_t display, GHOST_DisplaySetting &setting) const { SDL_DisplayMode mode; SDL_GetCurrentDisplayMode(display, &mode); @@ -98,7 +98,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplayModeSDL(SDL_DisplayMode } GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting( - GHOST_TUns8 display, const GHOST_DisplaySetting &setting) + uint8_t display, const GHOST_DisplaySetting &setting) { /* * Mode switching code ported from Quake 2 version 3.21 and bzflag version diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h index 9a79a842057..a719368275c 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerSDL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h @@ -37,21 +37,19 @@ class GHOST_DisplayManagerSDL : public GHOST_DisplayManager { public: GHOST_DisplayManagerSDL(GHOST_SystemSDL *system); - GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; + GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const; - GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const; + GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const; - GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, + GHOST_TSuccess getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const; - GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting &setting) const; + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const; GHOST_TSuccess getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const; - GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, - const GHOST_DisplaySetting &setting); + GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting); private: GHOST_SystemSDL *m_system; diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp index 3557c4cd0c5..2895ddd68a9 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp @@ -35,7 +35,7 @@ GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void) { } -GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8 &numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(uint8_t &numDisplays) const { numDisplays = ::GetSystemMetrics(SM_CMONITORS); return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure; @@ -54,8 +54,8 @@ static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd) * the information that was cached the last time the function was called with iModeNum * set to zero. */ -GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32 &numSettings) const +GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(uint8_t display, + int32_t &numSettings) const { DISPLAY_DEVICE display_device; if (!get_dd(display, &display_device)) @@ -69,8 +69,8 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 disp return GHOST_kSuccess; } -GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, +GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const { DISPLAY_DEVICE display_device; @@ -111,13 +111,13 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, } GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting( - GHOST_TUns8 display, GHOST_DisplaySetting &setting) const + uint8_t display, GHOST_DisplaySetting &setting) const { return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting); } GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting( - GHOST_TUns8 display, const GHOST_DisplaySetting &setting) + uint8_t display, const GHOST_DisplaySetting &setting) { DISPLAY_DEVICE display_device; if (!get_dd(display, &display_device)) diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h index 2de866b04ec..31cde2fc63d 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h +++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h @@ -45,7 +45,7 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { * \param numDisplays: The number of displays on this system. * \return Indication of success. */ - GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; + GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const; /** * Returns the number of display settings for this display device. @@ -53,7 +53,7 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { * \param numSetting: The number of settings of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const; + GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const; /** * Returns the current setting for this display device. @@ -62,8 +62,8 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { * \param setting: The setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, + GHOST_TSuccess getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const; /** @@ -72,8 +72,7 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting &setting) const; + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const; /** * Changes the current setting for this display device. @@ -81,8 +80,7 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, - const GHOST_DisplaySetting &setting); + GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting); protected: }; diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index f1acf74ca41..2ebdf8b3f2a 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -40,14 +40,14 @@ GHOST_DisplayManagerX11::GHOST_DisplayManagerX11(GHOST_SystemX11 *system) /* nothing to do. */ } -GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplays(GHOST_TUns8 &numDisplays) const +GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplays(uint8_t &numDisplays) const { numDisplays = m_system->getNumDisplays(); return GHOST_kSuccess; } -GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32 &numSettings) const +GHOST_TSuccess GHOST_DisplayManagerX11::getNumDisplaySettings(uint8_t display, + int32_t &numSettings) const { #ifdef WITH_X11_XF86VMODE int majorVersion, minorVersion; @@ -88,8 +88,8 @@ static int calculate_rate(XF86VidModeModeInfo *info) } #endif -GHOST_TSuccess GHOST_DisplayManagerX11::getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, +GHOST_TSuccess GHOST_DisplayManagerX11::getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const { Display *dpy = m_system->getXDisplay(); @@ -140,7 +140,7 @@ GHOST_TSuccess GHOST_DisplayManagerX11::getDisplaySetting(GHOST_TUns8 display, } GHOST_TSuccess GHOST_DisplayManagerX11::getCurrentDisplaySetting( - GHOST_TUns8 display, GHOST_DisplaySetting &setting) const + uint8_t display, GHOST_DisplaySetting &setting) const { /* According to the xf86vidmodegetallmodelines man page, * "The first element of the array corresponds to the current video mode." @@ -149,7 +149,7 @@ GHOST_TSuccess GHOST_DisplayManagerX11::getCurrentDisplaySetting( } GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting( - GHOST_TUns8 /*display*/, const GHOST_DisplaySetting &setting) + uint8_t /*display*/, const GHOST_DisplaySetting &setting) { #ifdef WITH_X11_XF86VMODE /* Mode switching code ported from SDL: diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h index e0fc1cc1210..52702a397d7 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.h +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h @@ -43,7 +43,7 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { * \param numDisplays: The number of displays on this system. * \return Indication of success. */ - GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; + GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const; /** * Returns the number of display settings for this display device. @@ -51,7 +51,7 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { * \param numSetting: The number of settings of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const; + GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const; /** * Returns the current setting for this display device. @@ -60,8 +60,8 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { * \param setting: The setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, - GHOST_TInt32 index, + GHOST_TSuccess getDisplaySetting(uint8_t display, + int32_t index, GHOST_DisplaySetting &setting) const; /** @@ -70,8 +70,7 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting &setting) const; + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const; /** * Changes the current setting for this display device. @@ -79,8 +78,7 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { * \param setting: The current setting of the display device with this index. * \return Indication of success. */ - GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, - const GHOST_DisplaySetting &setting); + GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting); private: GHOST_SystemX11 *m_system; diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp index ab4b48da9b4..c51bd58898b 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp @@ -242,7 +242,7 @@ void *GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject *pDataObject) strArray = (GHOST_TStringArray *)::malloc(sizeof(GHOST_TStringArray)); strArray->count = 0; - strArray->strings = (GHOST_TUns8 **)::malloc(totfiles * sizeof(GHOST_TUns8 *)); + strArray->strings = (uint8_t **)::malloc(totfiles * sizeof(uint8_t *)); for (UINT nfile = 0; nfile < totfiles; nfile++) { if (::DragQueryFileW(hdrop, nfile, fpath, MAX_PATH) > 0) { @@ -251,7 +251,7 @@ void *GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject *pDataObject) } // Just ignore paths that could not be converted verbatim. - strArray->strings[nvalid] = (GHOST_TUns8 *)temp_path; + strArray->strings[nvalid] = (uint8_t *)temp_path; strArray->count = nvalid + 1; nvalid++; } diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp index a62db31c952..8758a27930e 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.cpp +++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp @@ -216,7 +216,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr strArray = (GHOST_TStringArray *)malloc(sizeof(GHOST_TStringArray)); strArray->count = 0; - strArray->strings = (GHOST_TUns8 **)malloc(totPaths * sizeof(GHOST_TUns8 *)); + strArray->strings = (uint8_t **)malloc(totPaths * sizeof(uint8_t *)); curLength = 0; for (int i = 0; i <= dropBufferSize; i++) { @@ -230,7 +230,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr decodedPath = FileUrlDecode(curPath); if (decodedPath) { - strArray->strings[strArray->count] = (GHOST_TUns8 *)decodedPath; + strArray->strings[strArray->count] = (uint8_t *)decodedPath; strArray->count++; } diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h index 5016ca0e117..0194afd559c 100644 --- a/intern/ghost/intern/GHOST_Event.h +++ b/intern/ghost/intern/GHOST_Event.h @@ -37,7 +37,7 @@ class GHOST_Event : public GHOST_IEvent { * \param type: The type of this event. * \param window: The generating window (or NULL if system event). */ - GHOST_Event(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window) + GHOST_Event(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window) : m_type(type), m_time(msec), m_window(window), m_data(NULL) { } @@ -55,7 +55,7 @@ class GHOST_Event : public GHOST_IEvent { * Returns the time this event was generated. * \return The event generation time. */ - GHOST_TUns64 getTime() + uint64_t getTime() { return m_time; } @@ -83,7 +83,7 @@ class GHOST_Event : public GHOST_IEvent { /** Type of this event. */ GHOST_TEventType m_type; /** The time this event was generated. */ - GHOST_TUns64 m_time; + uint64_t m_time; /** Pointer to the generating window. */ GHOST_IWindow *m_window; /** Pointer to the event data. */ diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h index 02804efdcba..02563254a82 100644 --- a/intern/ghost/intern/GHOST_EventButton.h +++ b/intern/ghost/intern/GHOST_EventButton.h @@ -40,7 +40,7 @@ class GHOST_EventButton : public GHOST_Event { * \param button: The state of the buttons were at the time of the event. * \param tablet: The tablet data associated with this event. */ - GHOST_EventButton(GHOST_TUns64 time, + GHOST_EventButton(uint64_t time, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask button, diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h index d83ff6af6ce..facbab0855d 100644 --- a/intern/ghost/intern/GHOST_EventCursor.h +++ b/intern/ghost/intern/GHOST_EventCursor.h @@ -39,11 +39,11 @@ class GHOST_EventCursor : public GHOST_Event { * \param y: The y-coordinate of the location the cursor was at the time of the event. * \param tablet: The tablet data associated with this event. */ - GHOST_EventCursor(GHOST_TUns64 msec, + GHOST_EventCursor(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, - GHOST_TInt32 x, - GHOST_TInt32 y, + int32_t x, + int32_t y, const GHOST_TabletData &tablet) : GHOST_Event(msec, type, window), m_cursorEventData({x, y, tablet}) { diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h index a86b8302bf5..537717b1717 100644 --- a/intern/ghost/intern/GHOST_EventDragnDrop.h +++ b/intern/ghost/intern/GHOST_EventDragnDrop.h @@ -72,7 +72,7 @@ class GHOST_EventDragnDrop : public GHOST_Event { * \param y: The y-coordinate of the location the cursor was at the time of the event. * \param data: The "content" dropped in the window. */ - GHOST_EventDragnDrop(GHOST_TUns64 time, + GHOST_EventDragnDrop(uint64_t time, GHOST_TEventType type, GHOST_TDragnDropTypes dataType, GHOST_IWindow *window, diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h index 1e6a3284a51..93e6f0380da 100644 --- a/intern/ghost/intern/GHOST_EventKey.h +++ b/intern/ghost/intern/GHOST_EventKey.h @@ -39,11 +39,8 @@ class GHOST_EventKey : public GHOST_Event { * \param type: The type of key event. * \param key: The key code of the key. */ - GHOST_EventKey(GHOST_TUns64 msec, - GHOST_TEventType type, - GHOST_IWindow *window, - GHOST_TKey key, - bool is_repeat) + GHOST_EventKey( + uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TKey key, bool is_repeat) : GHOST_Event(msec, type, window) { m_keyEventData.key = key; @@ -60,7 +57,7 @@ class GHOST_EventKey : public GHOST_Event { * \param key: The key code of the key. * \param ascii: The ascii code for the key event. */ - GHOST_EventKey(GHOST_TUns64 msec, + GHOST_EventKey(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TKey key, diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp index 72101d4610f..15befb9afcb 100644 --- a/intern/ghost/intern/GHOST_EventManager.cpp +++ b/intern/ghost/intern/GHOST_EventManager.cpp @@ -45,14 +45,14 @@ GHOST_EventManager::~GHOST_EventManager() } } -GHOST_TUns32 GHOST_EventManager::getNumEvents() +uint32_t GHOST_EventManager::getNumEvents() { - return (GHOST_TUns32)m_events.size(); + return (uint32_t)m_events.size(); } -GHOST_TUns32 GHOST_EventManager::getNumEvents(GHOST_TEventType type) +uint32_t GHOST_EventManager::getNumEvents(GHOST_TEventType type) { - GHOST_TUns32 numEvents = 0; + uint32_t numEvents = 0; TEventStack::iterator p; for (p = m_events.begin(); p != m_events.end(); ++p) { if ((*p)->getType() == type) { diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h index a372eb96a99..ba936e449f5 100644 --- a/intern/ghost/intern/GHOST_EventManager.h +++ b/intern/ghost/intern/GHOST_EventManager.h @@ -53,14 +53,14 @@ class GHOST_EventManager { * Returns the number of events currently on the stack. * \return The number of events on the stack. */ - GHOST_TUns32 getNumEvents(); + uint32_t getNumEvents(); /** * Returns the number of events of a certain type currently on the stack. * \param type: The type of events to be counted. * \return The number of events on the stack of this type. */ - GHOST_TUns32 getNumEvents(GHOST_TEventType type); + uint32_t getNumEvents(GHOST_TEventType type); /** * Pushes an event on the stack. diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h index 64e67434b74..10f39f4be66 100644 --- a/intern/ghost/intern/GHOST_EventNDOF.h +++ b/intern/ghost/intern/GHOST_EventNDOF.h @@ -31,7 +31,7 @@ class GHOST_EventNDOFMotion : public GHOST_Event { GHOST_TEventNDOFMotionData m_axisData; public: - GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow *window) + GHOST_EventNDOFMotion(uint64_t time, GHOST_IWindow *window) : GHOST_Event(time, GHOST_kEventNDOFMotion, window) { m_data = &m_axisData; @@ -43,7 +43,7 @@ class GHOST_EventNDOFButton : public GHOST_Event { GHOST_TEventNDOFButtonData m_buttonData; public: - GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow *window) + GHOST_EventNDOFButton(uint64_t time, GHOST_IWindow *window) : GHOST_Event(time, GHOST_kEventNDOFButton, window) { m_data = &m_buttonData; diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp index fb34b1d3b1a..48043fa709b 100644 --- a/intern/ghost/intern/GHOST_EventPrinter.cpp +++ b/intern/ghost/intern/GHOST_EventPrinter.cpp @@ -39,7 +39,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event) if (event->getType() == GHOST_kEventWindowUpdate) return false; - std::cout << "GHOST_EventPrinter::processEvent, time: " << (GHOST_TInt32)event->getTime() + std::cout << "GHOST_EventPrinter::processEvent, time: " << (int32_t)event->getTime() << ", type: "; switch (event->getType()) { case GHOST_kEventUnknown: diff --git a/intern/ghost/intern/GHOST_EventString.h b/intern/ghost/intern/GHOST_EventString.h index 6dd2ffb2e86..a457c2e058a 100644 --- a/intern/ghost/intern/GHOST_EventString.h +++ b/intern/ghost/intern/GHOST_EventString.h @@ -38,7 +38,7 @@ class GHOST_EventString : public GHOST_Event { * \param window: The generating window (or NULL if system event). * \param data_ptr: Pointer to the (un-formatted) data associated with the event. */ - GHOST_EventString(GHOST_TUns64 msec, + GHOST_EventString(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TEventDataPtr data_ptr) diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h index d4f9d0f2b55..58420f6d713 100644 --- a/intern/ghost/intern/GHOST_EventTrackpad.h +++ b/intern/ghost/intern/GHOST_EventTrackpad.h @@ -39,13 +39,13 @@ class GHOST_EventTrackpad : public GHOST_Event { * \param x: The x-delta of the pan event. * \param y: The y-delta of the pan event. */ - GHOST_EventTrackpad(GHOST_TUns64 msec, + GHOST_EventTrackpad(uint64_t msec, GHOST_IWindow *window, GHOST_TTrackpadEventSubTypes subtype, - GHOST_TInt32 x, - GHOST_TInt32 y, - GHOST_TInt32 deltaX, - GHOST_TInt32 deltaY, + int32_t x, + int32_t y, + int32_t deltaX, + int32_t deltaY, bool isDirectionInverted) : GHOST_Event(msec, GHOST_kEventTrackpad, window) { diff --git a/intern/ghost/intern/GHOST_EventWheel.h b/intern/ghost/intern/GHOST_EventWheel.h index ea62e02d08d..666b3c7aba6 100644 --- a/intern/ghost/intern/GHOST_EventWheel.h +++ b/intern/ghost/intern/GHOST_EventWheel.h @@ -39,7 +39,7 @@ class GHOST_EventWheel : public GHOST_Event { * \param window: The window of this event. * \param z: The displacement of the mouse wheel. */ - GHOST_EventWheel(GHOST_TUns64 msec, GHOST_IWindow *window, GHOST_TInt32 z) + GHOST_EventWheel(uint64_t msec, GHOST_IWindow *window, int32_t z) : GHOST_Event(msec, GHOST_kEventWheel, window) { m_wheelEventData.z = z; diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h index 0c851e067e8..4af988aef6e 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.h +++ b/intern/ghost/intern/GHOST_ImeWin32.h @@ -44,7 +44,7 @@ class GHOST_EventIME : public GHOST_Event { * \param type: The type of key event. * \param key: The key code of the key. */ - GHOST_EventIME(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata) + GHOST_EventIME(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata) : GHOST_Event(msec, type, window) { this->m_data = customdata; diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h index e94ccef08c0..f951cae3a41 100644 --- a/intern/ghost/intern/GHOST_ModifierKeys.h +++ b/intern/ghost/intern/GHOST_ModifierKeys.h @@ -72,17 +72,17 @@ struct GHOST_ModifierKeys { bool equals(const GHOST_ModifierKeys &keys) const; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_LeftShift : 1; + uint8_t m_LeftShift : 1; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_RightShift : 1; + uint8_t m_RightShift : 1; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_LeftAlt : 1; + uint8_t m_LeftAlt : 1; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_RightAlt : 1; + uint8_t m_RightAlt : 1; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_LeftControl : 1; + uint8_t m_LeftControl : 1; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_RightControl : 1; + uint8_t m_RightControl : 1; /** Bitfield that stores the appropriate key state. */ - GHOST_TUns8 m_OS : 1; + uint8_t m_OS : 1; }; diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index dda78c0ac5b..079ad67f737 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -279,14 +279,14 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ return m_deviceType != NDOF_UnknownDevice; } -void GHOST_NDOFManager::updateTranslation(const int t[3], GHOST_TUns64 time) +void GHOST_NDOFManager::updateTranslation(const int t[3], uint64_t time) { memcpy(m_translation, t, sizeof(m_translation)); m_motionTime = time; m_motionEventPending = true; } -void GHOST_NDOFManager::updateRotation(const int r[3], GHOST_TUns64 time) +void GHOST_NDOFManager::updateRotation(const int r[3], uint64_t time) { memcpy(m_rotation, r, sizeof(m_rotation)); m_motionTime = time; @@ -295,7 +295,7 @@ void GHOST_NDOFManager::updateRotation(const int r[3], GHOST_TUns64 time) void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, - GHOST_TUns64 time, + uint64_t time, GHOST_IWindow *window) { GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST, @@ -316,7 +316,7 @@ void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key, bool press, - GHOST_TUns64 time, + uint64_t time, GHOST_IWindow *window) { GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; @@ -329,7 +329,7 @@ void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key, m_system.pushEvent(event); } -void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 time) +void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t time) { GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow(); @@ -371,7 +371,7 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 } } -void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time) +void GHOST_NDOFManager::updateButtons(int button_bits, uint64_t time) { button_bits &= m_buttonMask; // discard any "garbage" bits diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h index d0b49bc13c2..7be129c327c 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.h +++ b/intern/ghost/intern/GHOST_NDOFManager.h @@ -130,13 +130,13 @@ class GHOST_NDOFManager { // rotations are + when CCW, - when CW // each platform is responsible for getting axis data into this form // these values should not be scaled (just shuffled or flipped) - void updateTranslation(const int t[3], GHOST_TUns64 time); - void updateRotation(const int r[3], GHOST_TUns64 time); + void updateTranslation(const int t[3], uint64_t time); + void updateRotation(const int r[3], uint64_t time); // the latest raw button data from the device // use HID button encoding (not NDOF_ButtonT) - void updateButton(int button_number, bool press, GHOST_TUns64 time); - void updateButtons(int button_bits, GHOST_TUns64 time); + void updateButton(int button_number, bool press, uint64_t time); + void updateButtons(int button_bits, uint64_t time); // NDOFButton events are sent immediately // processes and sends most recent raw data as an NDOFMotion event @@ -147,8 +147,8 @@ class GHOST_NDOFManager { GHOST_System &m_system; private: - void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, GHOST_IWindow *); - void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, GHOST_IWindow *); + void sendButtonEvent(NDOF_ButtonT, bool press, uint64_t time, GHOST_IWindow *); + void sendKeyEvent(GHOST_TKey, bool press, uint64_t time, GHOST_IWindow *); NDOF_DeviceT m_deviceType; int m_buttonCount; @@ -159,8 +159,8 @@ class GHOST_NDOFManager { int m_rotation[3]; int m_buttons; // bit field - GHOST_TUns64 m_motionTime; // in milliseconds - GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent + uint64_t m_motionTime; // in milliseconds + uint64_t m_prevMotionTime; // time of most recent Motion event sent GHOST_TProgress m_motionState; bool m_motionEventPending; diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm index 5274b2d1ba9..63a38fd9297 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm +++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm @@ -195,7 +195,7 @@ static void DeviceEvent(uint32_t unused, uint32_t msg_type, void *msg_arg) // device state is broadcast to all clients; only react if sent to us if (s->client == clientID) { // TODO: is s->time compatible with GHOST timestamps? if so use that instead. - GHOST_TUns64 now = ghost_system->getMilliSeconds(); + uint64_t now = ghost_system->getMilliSeconds(); switch (s->command) { case kConnexionCmdHandleAxis: { diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp index 8ed0af1fc29..983bb38307e 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp +++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp @@ -97,7 +97,7 @@ bool GHOST_NDOFManagerUnix::processEvents() switch (e.type) { case SPNAV_EVENT_MOTION: { /* convert to blender view coords */ - GHOST_TUns64 now = m_system.getMilliSeconds(); + uint64_t now = m_system.getMilliSeconds(); const int t[3] = {(int)e.motion.x, (int)e.motion.y, (int)-e.motion.z}; const int r[3] = {(int)-e.motion.rx, (int)-e.motion.ry, (int)e.motion.rz}; @@ -109,7 +109,7 @@ bool GHOST_NDOFManagerUnix::processEvents() break; } case SPNAV_EVENT_BUTTON: - GHOST_TUns64 now = m_system.getMilliSeconds(); + uint64_t now = m_system.getMilliSeconds(); updateButton(e.button.bnum, e.button.press, now); break; } @@ -118,7 +118,7 @@ bool GHOST_NDOFManagerUnix::processEvents() #ifdef USE_FINISH_GLITCH_WORKAROUND if (motion_test_prev == true && motion_test == false) { - GHOST_TUns64 now = m_system.getMilliSeconds(); + uint64_t now = m_system.getMilliSeconds(); const int v[3] = {0, 0, 0}; updateTranslation(v, now); diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp index c82e9819f3c..4f4d1d5a1c8 100644 --- a/intern/ghost/intern/GHOST_Path-api.cpp +++ b/intern/ghost/intern/GHOST_Path-api.cpp @@ -38,25 +38,25 @@ GHOST_TSuccess GHOST_DisposeSystemPaths(void) return GHOST_ISystemPaths::dispose(); } -const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr) +const char *GHOST_getSystemDir(int version, const char *versionstr) { GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); return systemPaths ? systemPaths->getSystemDir(version, versionstr) : NULL; } -const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr) +const char *GHOST_getUserDir(int version, const char *versionstr) { GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */ } -const GHOST_TUns8 *GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type) +const char *GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type) { GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); return systemPaths ? systemPaths->getUserSpecialDir(type) : NULL; /* shouldn't be NULL */ } -const GHOST_TUns8 *GHOST_getBinaryDir() +const char *GHOST_getBinaryDir() { GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); return systemPaths ? systemPaths->getBinaryDir() : NULL; /* shouldn't be NULL */ diff --git a/intern/ghost/intern/GHOST_Rect.cpp b/intern/ghost/intern/GHOST_Rect.cpp index c5b9bc44468..8ef9486f35a 100644 --- a/intern/ghost/intern/GHOST_Rect.cpp +++ b/intern/ghost/intern/GHOST_Rect.cpp @@ -23,7 +23,7 @@ #include "GHOST_Rect.h" -void GHOST_Rect::inset(GHOST_TInt32 i) +void GHOST_Rect::inset(int32_t i) { if (i > 0) { // Grow the rectangle @@ -34,7 +34,7 @@ void GHOST_Rect::inset(GHOST_TInt32 i) } else if (i < 0) { // Shrink the rectangle, check for insets larger than half the size - GHOST_TInt32 i2 = i * 2; + int32_t i2 = i * 2; if (getWidth() > i2) { m_l += i; m_r -= i; @@ -82,9 +82,9 @@ GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect &r) const return v; } -void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy) +void GHOST_Rect::setCenter(int32_t cx, int32_t cy) { - GHOST_TInt32 offset = cx - (m_l + (m_r - m_l) / 2); + int32_t offset = cx - (m_l + (m_r - m_l) / 2); m_l += offset; m_r += offset; offset = cy - (m_t + (m_b - m_t) / 2); @@ -92,7 +92,7 @@ void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy) m_b += offset; } -void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h) +void GHOST_Rect::setCenter(int32_t cx, int32_t cy, int32_t w, int32_t h) { long w_2, h_2; diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 46c50045b80..f6659cf50dc 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -56,19 +56,19 @@ GHOST_System::~GHOST_System() exit(); } -GHOST_TUns64 GHOST_System::getMilliSeconds() const +uint64_t GHOST_System::getMilliSeconds() const { return std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::steady_clock::now().time_since_epoch()) .count(); } -GHOST_ITimerTask *GHOST_System::installTimer(GHOST_TUns64 delay, - GHOST_TUns64 interval, +GHOST_ITimerTask *GHOST_System::installTimer(uint64_t delay, + uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData) { - GHOST_TUns64 millis = getMilliSeconds(); + uint64_t millis = getMilliSeconds(); GHOST_TimerTask *timer = new GHOST_TimerTask(millis + delay, interval, timerProc, userData); if (timer) { if (m_timerManager->addTimer(timer) == GHOST_kSuccess) { diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index 87ba0ae9c8c..9164687c5b5 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -75,7 +75,7 @@ class GHOST_System : public GHOST_ISystem { * Based on ANSI clock() routine. * \return The number of milliseconds. */ - virtual GHOST_TUns64 getMilliSeconds() const; + virtual uint64_t getMilliSeconds() const; /** * Installs a timer. @@ -89,8 +89,8 @@ class GHOST_System : public GHOST_ISystem { * \param userData: Placeholder for user data. * \return A timer task (0 if timer task installation failed). */ - GHOST_ITimerTask *installTimer(GHOST_TUns64 delay, - GHOST_TUns64 interval, + GHOST_ITimerTask *installTimer(uint64_t delay, + uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = NULL); @@ -210,8 +210,8 @@ class GHOST_System : public GHOST_ISystem { /** * Inherited from GHOST_ISystem but left pure virtual * <pre> - * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0; - * GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) + * GHOST_TSuccess getCursorPosition(int32_t& x, int32_t& y) const = 0; + * GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) * </pre> */ @@ -308,14 +308,14 @@ class GHOST_System : public GHOST_ISystem { * \return Returns the clipboard data * */ - virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; + virtual char *getClipboard(bool selection) const = 0; /** * Put data to the Clipboard * \param buffer: The buffer to copy to the clipboard. * \param selection: The clipboard to copy too only used on X11. */ - virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; + virtual void putClipboard(const char *buffer, bool selection) const = 0; /** * Show a system message box diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 088a9213373..48a64b155fc 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -59,7 +59,7 @@ class GHOST_SystemCocoa : public GHOST_System { * Based on ANSI clock() routine. * \return The number of milliseconds. */ - GHOST_TUns64 getMilliSeconds() const; + uint64_t getMilliSeconds() const; /*************************************************************************************** * Display/window management functionality @@ -69,18 +69,18 @@ class GHOST_SystemCocoa : public GHOST_System { * Returns the number of displays on this system. * \return The number of displays. */ - GHOST_TUns8 getNumDisplays() const; + uint8_t getNumDisplays() const; /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ - void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const; /** Returns the combine dimensions of all monitors. * \return The dimension of the workspace. */ - void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const; /** * Create a new window. @@ -100,10 +100,10 @@ class GHOST_SystemCocoa : public GHOST_System { * \return The new window (or 0 if creation failed). */ GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -175,7 +175,7 @@ class GHOST_SystemCocoa : public GHOST_System { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const; /** * Updates the location of the cursor (location in screen coordinates). @@ -183,7 +183,7 @@ class GHOST_SystemCocoa : public GHOST_System { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + GHOST_TSuccess setCursorPosition(int32_t x, int32_t y); /*************************************************************************************** * Access to mouse button and keyboard states. @@ -208,14 +208,14 @@ class GHOST_SystemCocoa : public GHOST_System { * \param selection: Indicate which buffer to return. * \return Returns the selected buffer */ - GHOST_TUns8 *getClipboard(bool selection) const; + char *getClipboard(bool selection) const; /** * Puts buffer to system clipboard * \param buffer: The buffer to be copied. * \param selection: Indicates which buffer to copy too, only used on X11. */ - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + void putClipboard(const char *buffer, bool selection) const; /** * Handles a window event. Called by GHOST_WindowCocoa window delegate @@ -288,10 +288,10 @@ class GHOST_SystemCocoa : public GHOST_System { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + GHOST_TSuccess setMouseCursorPosition(int32_t x, int32_t y); /** Start time at initialization. */ - GHOST_TUns64 m_start_time; + uint64_t m_start_time; /** Event has been processed directly by Cocoa (or NDOF manager) * and has sent a ghost event to be dispatched */ @@ -302,7 +302,7 @@ class GHOST_SystemCocoa : public GHOST_System { bool m_needDelayedApplicationBecomeActiveEventProcessing; /** State of the modifiers. */ - GHOST_TUns32 m_modifierMask; + uint32_t m_modifierMask; /** Ignores window size messages (when window is dragged). */ bool m_ignoreWindowSizedMessages; diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 218c91d05a3..0f10d5815f4 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -655,7 +655,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init() #pragma mark window management -GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const +uint64_t GHOST_SystemCocoa::getMilliSeconds() const { // Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime]) struct timeval currentTime; @@ -667,7 +667,7 @@ GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const return ((currentTime.tv_sec * 1000) + (currentTime.tv_usec / 1000) - m_start_time); } -GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const +uint8_t GHOST_SystemCocoa::getNumDisplays() const { // Note that OS X supports monitor hot plug // We do not support multiple monitors at the moment @@ -676,7 +676,7 @@ GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const } } -void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemCocoa::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { @autoreleasepool { // Get visible frame, that is frame excluding dock and top menu bar @@ -693,17 +693,17 @@ void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns } } -void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemCocoa::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { /* TODO! */ getMainDisplayDimensions(width, height); } GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -721,7 +721,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title, styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable)]; - GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top; + int32_t bottom = (contentRect.size.height - 1) - height - top; // Ensures window top left is inside this available rect left = left > contentRect.origin.x ? left : contentRect.origin.x; @@ -791,20 +791,20 @@ GHOST_TSuccess GHOST_SystemCocoa::disposeContext(GHOST_IContext *context) /** * \note : returns coordinates in Cocoa screen coordinates */ -GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const +GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(int32_t &x, int32_t &y) const { NSPoint mouseLoc = [NSEvent mouseLocation]; // Returns the mouse location in screen coordinates - x = (GHOST_TInt32)mouseLoc.x; - y = (GHOST_TInt32)mouseLoc.y; + x = (int32_t)mouseLoc.x; + y = (int32_t)mouseLoc.y; return GHOST_kSuccess; } /** * \note : expect Cocoa screen coordinates */ -GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(int32_t x, int32_t y) { GHOST_WindowCocoa *window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow(); if (!window) @@ -824,7 +824,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 return GHOST_kSuccess; } -GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(int32_t x, int32_t y) { float xf = (float)x, yf = (float)y; GHOST_WindowCocoa *window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow(); @@ -897,7 +897,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) GHOST_TimerManager* timerMgr = getTimerManager(); if (waitForEvent) { - GHOST_TUns64 next = timerMgr->nextFireTime(); + uint64_t next = timerMgr->nextFireTime(); double timeOut; if (next == GHOST_kFireTimeNever) { @@ -1132,7 +1132,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType break; case GHOST_kEventDraggingDropDone: { - GHOST_TUns8 *temp_buff; + uint8_t *temp_buff; GHOST_TStringArray *strArray; NSArray *droppedArray; size_t pastedTextSize; @@ -1157,13 +1157,13 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType return GHOST_kFailure; } - strArray->strings = (GHOST_TUns8 **)malloc(strArray->count * sizeof(GHOST_TUns8 *)); + strArray->strings = (uint8_t **)malloc(strArray->count * sizeof(uint8_t *)); for (i = 0; i < strArray->count; i++) { droppedStr = [droppedArray objectAtIndex:i]; pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1); + temp_buff = (uint8_t *)malloc(pastedTextSize + 1); if (!temp_buff) { strArray->count = i; @@ -1185,7 +1185,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType droppedStr = (NSString *)data; pastedTextSize = [droppedStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1); + temp_buff = (uint8_t *)malloc(pastedTextSize + 1); if (temp_buff == NULL) { return GHOST_kFailure; @@ -1204,9 +1204,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType NSImage *droppedImg = (NSImage *)data; NSSize imgSize = [droppedImg size]; ImBuf *ibuf = NULL; - GHOST_TUns8 *rasterRGB = NULL; - GHOST_TUns8 *rasterRGBA = NULL; - GHOST_TUns8 *toIBuf = NULL; + uint8_t *rasterRGB = NULL; + uint8_t *rasterRGBA = NULL; + uint8_t *toIBuf = NULL; int x, y, to_i, from_i; NSBitmapImageRep *blBitmapFormatImageRGB, *blBitmapFormatImageRGBA, *bitmapImage = nil; NSEnumerator *enumerator; @@ -1232,8 +1232,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) && ![bitmapImage isPlanar]) { /* Try a fast copy if the image is a meshed RGBA 32bit bitmap. */ - toIBuf = (GHOST_TUns8 *)ibuf->rect; - rasterRGB = (GHOST_TUns8 *)[bitmapImage bitmapData]; + toIBuf = (uint8_t *)ibuf->rect; + rasterRGB = (uint8_t *)[bitmapImage bitmapData]; for (y = 0; y < imgSize.height; y++) { to_i = (imgSize.height - y - 1) * imgSize.width; from_i = y * imgSize.width; @@ -1270,7 +1270,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType [bitmapImage draw]; [NSGraphicsContext restoreGraphicsState]; - rasterRGB = (GHOST_TUns8 *)[blBitmapFormatImageRGB bitmapData]; + rasterRGB = (uint8_t *)[blBitmapFormatImageRGB bitmapData]; if (rasterRGB == NULL) { [bitmapImage release]; [blBitmapFormatImageRGB release]; @@ -1299,7 +1299,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType [bitmapImage draw]; [NSGraphicsContext restoreGraphicsState]; - rasterRGBA = (GHOST_TUns8 *)[blBitmapFormatImageRGBA bitmapData]; + rasterRGBA = (uint8_t *)[blBitmapFormatImageRGBA bitmapData]; if (rasterRGBA == NULL) { [bitmapImage release]; [blBitmapFormatImageRGB release]; @@ -1309,7 +1309,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType } /* Copy the image to ibuf, flipping it vertically. */ - toIBuf = (GHOST_TUns8 *)ibuf->rect; + toIBuf = (uint8_t *)ibuf->rect; for (y = 0; y < imgSize.height; y++) { for (x = 0; x < imgSize.width; x++) { to_i = (imgSize.height - y - 1) * imgSize.width + x; @@ -1563,7 +1563,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) switch (grab_mode) { case GHOST_kGrabHide: // Cursor hidden grab operation : no cursor move { - GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y; + int32_t x_warp, y_warp, x_accum, y_accum, x, y; window->getCursorGrabInitPos(x_warp, y_warp); window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp); @@ -1593,8 +1593,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } NSPoint mousePos = [event locationInWindow]; - GHOST_TInt32 x_mouse = mousePos.x; - GHOST_TInt32 y_mouse = mousePos.y; + int32_t x_mouse = mousePos.x; + int32_t y_mouse = mousePos.y; GHOST_Rect bounds, windowBounds, correctedBounds; /* fallback to window bounds */ @@ -1610,19 +1610,19 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t; // Get accumulation from previous mouse warps - GHOST_TInt32 x_accum, y_accum; + int32_t x_accum, y_accum; window->getCursorGrabAccum(x_accum, y_accum); // Warp mouse cursor if needed - GHOST_TInt32 warped_x_mouse = x_mouse; - GHOST_TInt32 warped_y_mouse = y_mouse; + int32_t warped_x_mouse = x_mouse; + int32_t warped_y_mouse = y_mouse; correctedBounds.wrapPoint( warped_x_mouse, warped_y_mouse, 4, window->getCursorGrabAxis()); // Set new cursor position if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) { - GHOST_TInt32 warped_x, warped_y; + int32_t warped_x, warped_y; window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y); setMouseCursorPosition(warped_x, warped_y); /* wrap */ window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), @@ -1633,7 +1633,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } // Generate event - GHOST_TInt32 x, y; + int32_t x, y; window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y); pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, @@ -1646,7 +1646,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) default: { // Normal cursor operation: send mouse position in window NSPoint mousePos = [event locationInWindow]; - GHOST_TInt32 x, y; + int32_t x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventCursor([event timestamp] * 1000, @@ -1690,7 +1690,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) /* Standard scroll-wheel case, if no swiping happened, * and no momentum (kinetic scroll) works. */ if (!m_multiTouchScroll && momentumPhase == NSEventPhaseNone) { - GHOST_TInt32 delta; + int32_t delta; double deltaF = [event deltaY]; @@ -1704,7 +1704,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } else { NSPoint mousePos = [event locationInWindow]; - GHOST_TInt32 x, y; + int32_t x, y; double dx; double dy; @@ -1734,7 +1734,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSEventTypeMagnify: { NSPoint mousePos = [event locationInWindow]; - GHOST_TInt32 x, y; + int32_t x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, @@ -1748,7 +1748,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSEventTypeSmartMagnify: { NSPoint mousePos = [event locationInWindow]; - GHOST_TInt32 x, y; + int32_t x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventTrackpad( [event timestamp] * 1000, window, GHOST_kTrackpadEventSmartMagnify, x, y, 0, 0, false)); @@ -1756,7 +1756,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSEventTypeRotate: { NSPoint mousePos = [event locationInWindow]; - GHOST_TInt32 x, y; + int32_t x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, @@ -1933,9 +1933,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) #pragma mark Clipboard get/set -GHOST_TUns8 *GHOST_SystemCocoa::getClipboard(bool selection) const +char *GHOST_SystemCocoa::getClipboard(bool selection) const { - GHOST_TUns8 *temp_buff; + char *temp_buff; size_t pastedTextSize; @autoreleasepool { @@ -1950,14 +1950,13 @@ GHOST_TUns8 *GHOST_SystemCocoa::getClipboard(bool selection) const pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1); + temp_buff = (char *)malloc(pastedTextSize + 1); if (temp_buff == NULL) { return NULL; } - strncpy( - (char *)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize); + strncpy(temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize); temp_buff[pastedTextSize] = '\0'; @@ -1970,7 +1969,7 @@ GHOST_TUns8 *GHOST_SystemCocoa::getClipboard(bool selection) const } } -void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const +void GHOST_SystemCocoa::putClipboard(const char *buffer, bool selection) const { if (selection) return; // for copying the selection, used on X11 diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h index faeffffed9e..5dbc42b53a2 100644 --- a/intern/ghost/intern/GHOST_SystemNULL.h +++ b/intern/ghost/intern/GHOST_SystemNULL.h @@ -52,33 +52,33 @@ class GHOST_SystemNULL : public GHOST_System { { return GHOST_kSuccess; } - GHOST_TUns8 *getClipboard(bool selection) const + char *getClipboard(bool selection) const { return NULL; } - void putClipboard(GHOST_TInt8 *buffer, bool selection) const + void putClipboard(const char *buffer, bool selection) const { /* nop */ } - GHOST_TUns64 getMilliSeconds() const + uint64_t getMilliSeconds() const { return 0; } - GHOST_TUns8 getNumDisplays() const + uint8_t getNumDisplays() const { - return GHOST_TUns8(1); + return uint8_t(1); } - GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const { return GHOST_kFailure; } - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) + GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) { return GHOST_kFailure; } - void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const + void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { /* nop */ } - void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const + void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { /* nop */ } GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) @@ -106,10 +106,10 @@ class GHOST_SystemNULL : public GHOST_System { } GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, diff --git a/intern/ghost/intern/GHOST_SystemPaths.h b/intern/ghost/intern/GHOST_SystemPaths.h index ab53b2813cd..5bd52d44b42 100644 --- a/intern/ghost/intern/GHOST_SystemPaths.h +++ b/intern/ghost/intern/GHOST_SystemPaths.h @@ -49,20 +49,20 @@ class GHOST_SystemPaths : public GHOST_ISystemPaths { * "unpack and run" path, then look for properly installed path, including versioning. * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). */ - virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const = 0; + virtual const char *getSystemDir(int version, const char *versionstr) const = 0; /** * Determine the base dir in which user configuration is stored, including versioning. * If needed, it will create the base directory. * \return Unsigned char string pointing to user dir (eg ~/.blender/). */ - virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const = 0; + virtual const char *getUserDir(int version, const char *versionstr) const = 0; /** * Determine the directory of the current binary * \return Unsigned char string pointing to the binary dir */ - virtual const GHOST_TUns8 *getBinaryDir() const = 0; + virtual const char *getBinaryDir() const = 0; /** * Add the file to the operating system most recently used files diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h index 14633d46f03..1af63fc9b56 100644 --- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h +++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h @@ -46,26 +46,26 @@ class GHOST_SystemPathsCocoa : public GHOST_SystemPaths { * "unpack and run" path, then look for properly installed path, including versioning. * \return Unsigned char string pointing to system dir (eg /usr/share/blender/). */ - const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; + const char *getSystemDir(int version, const char *versionstr) const; /** * Determine the base dir in which user configuration is stored, including versioning. * If needed, it will create the base directory. * \return Unsigned char string pointing to user dir (eg ~/.blender/). */ - const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; + const char *getUserDir(int version, const char *versionstr) const; /** * Determine a special ("well known") and easy to reach user directory. * \return Unsigned char string pointing to user dir (eg `~/Documents/`). */ - const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const; + const char *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const; /** * Determine the directory of the current binary * \return Unsigned char string pointing to the binary dir */ - const GHOST_TUns8 *getBinaryDir() const; + const char *getBinaryDir() const; /** * Add the file to the operating system most recently used files diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm index 7c6184837bf..3b29d5106f6 100644 --- a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm @@ -36,7 +36,7 @@ GHOST_SystemPathsCocoa::~GHOST_SystemPathsCocoa() #pragma mark Base directories retrieval -const GHOST_TUns8 *GHOST_SystemPathsCocoa::getSystemDir(int, const char *versionstr) const +const char *GHOST_SystemPathsCocoa::getSystemDir(int, const char *versionstr) const { static char tempPath[512] = ""; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -60,10 +60,10 @@ const GHOST_TUns8 *GHOST_SystemPathsCocoa::getSystemDir(int, const char *version versionstr); [pool drain]; - return (GHOST_TUns8 *)tempPath; + return tempPath; } -const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserDir(int, const char *versionstr) const +const char *GHOST_SystemPathsCocoa::getUserDir(int, const char *versionstr) const { static char tempPath[512] = ""; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -87,10 +87,10 @@ const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserDir(int, const char *versionst versionstr); [pool drain]; - return (GHOST_TUns8 *)tempPath; + return tempPath; } -const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const +const char *GHOST_SystemPathsCocoa::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const { static char tempPath[512] = ""; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -138,12 +138,12 @@ const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserSpecialDir(GHOST_TUserSpecialD (char *)tempPath, [basePath cStringUsingEncoding:NSASCIIStringEncoding], sizeof(tempPath)); [pool drain]; - return (GHOST_TUns8 *)tempPath; + return tempPath; } -const GHOST_TUns8 *GHOST_SystemPathsCocoa::getBinaryDir() const +const char *GHOST_SystemPathsCocoa::getBinaryDir() const { - static GHOST_TUns8 tempPath[512] = ""; + static char tempPath[512] = ""; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *basePath; diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp index 86f3a0a31fb..b58799e9c2a 100644 --- a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp @@ -55,18 +55,18 @@ GHOST_SystemPathsUnix::~GHOST_SystemPathsUnix() { } -const GHOST_TUns8 *GHOST_SystemPathsUnix::getSystemDir(int, const char *versionstr) const +const char *GHOST_SystemPathsUnix::getSystemDir(int, const char *versionstr) const { /* no prefix assumes a portable build which only uses bundled scripts */ if (static_path) { static string system_path = string(static_path) + "/blender/" + versionstr; - return (GHOST_TUns8 *)system_path.c_str(); + return system_path.c_str(); } return NULL; } -const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *versionstr) const +const char *GHOST_SystemPathsUnix::getUserDir(int version, const char *versionstr) const { static string user_path = ""; static int last_version = 0; @@ -86,7 +86,7 @@ const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *ve return NULL; } } - return (GHOST_TUns8 *)user_path.c_str(); + return user_path.c_str(); } else { if (user_path.empty() || last_version != version) { @@ -107,11 +107,11 @@ const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *ve } } - return (const GHOST_TUns8 *)user_path.c_str(); + return user_path.c_str(); } } -const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const +const char *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const { const char *type_str; @@ -164,10 +164,10 @@ const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDi } path = path_stream.str(); - return path[0] ? (const GHOST_TUns8 *)path.c_str() : NULL; + return path[0] ? path.c_str() : NULL; } -const GHOST_TUns8 *GHOST_SystemPathsUnix::getBinaryDir() const +const char *GHOST_SystemPathsUnix::getBinaryDir() const { return NULL; } diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.h b/intern/ghost/intern/GHOST_SystemPathsUnix.h index bc9272ecd8f..37fb432e9e8 100644 --- a/intern/ghost/intern/GHOST_SystemPathsUnix.h +++ b/intern/ghost/intern/GHOST_SystemPathsUnix.h @@ -44,26 +44,26 @@ class GHOST_SystemPathsUnix : public GHOST_SystemPaths { * "unpack and run" path, then look for properly installed path, including versioning. * \return Unsigned char string pointing to system dir (eg `/usr/share/blender/`). */ - const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; + const char *getSystemDir(int version, const char *versionstr) const; /** * Determine the base dir in which user configuration is stored, including versioning. * If needed, it will create the base directory. * \return Unsigned char string pointing to user dir (eg `~/.config/.blender/`). */ - const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; + const char *getUserDir(int version, const char *versionstr) const; /** * Determine a special ("well known") and easy to reach user directory. * \return Unsigned char string pointing to user dir (eg `~/Documents/`). */ - const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const; + const char *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const; /** * Determine the directory of the current binary * \return Unsigned char string pointing to the binary dir */ - const GHOST_TUns8 *getBinaryDir() const; + const char *getBinaryDir() const; /** * Add the file to the operating system most recently used files diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp index 47e71b0d733..580cfcac7ba 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp @@ -38,7 +38,7 @@ GHOST_SystemPathsWin32::~GHOST_SystemPathsWin32() { } -const GHOST_TUns8 *GHOST_SystemPathsWin32::getSystemDir(int, const char *versionstr) const +const char *GHOST_SystemPathsWin32::getSystemDir(int, const char *versionstr) const { /* 1 utf-16 might translate into 3 utf-8. 2 utf-16 translates into 4 utf-8. */ static char knownpath[MAX_PATH * 3 + 128] = {0}; @@ -52,13 +52,13 @@ const GHOST_TUns8 *GHOST_SystemPathsWin32::getSystemDir(int, const char *version CoTaskMemFree(knownpath_16); strcat(knownpath, "\\Blender Foundation\\Blender\\"); strcat(knownpath, versionstr); - return (GHOST_TUns8 *)knownpath; + return knownpath; } return NULL; } -const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserDir(int, const char *versionstr) const +const char *GHOST_SystemPathsWin32::getUserDir(int, const char *versionstr) const { static char knownpath[MAX_PATH * 3 + 128] = {0}; PWSTR knownpath_16 = NULL; @@ -71,13 +71,13 @@ const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserDir(int, const char *versionst CoTaskMemFree(knownpath_16); strcat(knownpath, "\\Blender Foundation\\Blender\\"); strcat(knownpath, versionstr); - return (GHOST_TUns8 *)knownpath; + return knownpath; } return NULL; } -const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const +const char *GHOST_SystemPathsWin32::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const { GUID folderid; @@ -114,21 +114,21 @@ const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserSpecialDir(GHOST_TUserSpecialD if (hResult == S_OK) { conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3); CoTaskMemFree(knownpath_16); - return (GHOST_TUns8 *)knownpath; + return knownpath; } CoTaskMemFree(knownpath_16); return NULL; } -const GHOST_TUns8 *GHOST_SystemPathsWin32::getBinaryDir() const +const char *GHOST_SystemPathsWin32::getBinaryDir() const { static char fullname[MAX_PATH * 3] = {0}; wchar_t fullname_16[MAX_PATH * 3]; if (GetModuleFileNameW(0, fullname_16, MAX_PATH)) { conv_utf_16_to_8(fullname_16, fullname, MAX_PATH * 3); - return (GHOST_TUns8 *)fullname; + return fullname; } return NULL; diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h index 45e03e744a5..c9f7f6b987f 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.h +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h @@ -53,26 +53,26 @@ class GHOST_SystemPathsWin32 : public GHOST_SystemPaths { * "unpack and run" path, then look for properly installed path, including versioning. * \return Unsigned char string pointing to system dir (eg /usr/share/). */ - const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const; + const char *getSystemDir(int version, const char *versionstr) const; /** * Determine the base dir in which user configuration is stored, including versioning. * If needed, it will create the base directory. * \return Unsigned char string pointing to user dir (eg ~/). */ - const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const; + const char *getUserDir(int version, const char *versionstr) const; /** * Determine a special ("well known") and easy to reach user directory. * \return Unsigned char string pointing to user dir (eg `~/Documents/`). */ - const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const; + const char *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const; /** * Determine the directory of the current binary * \return Unsigned char string pointing to the binary dir */ - const GHOST_TUns8 *getBinaryDir() const; + const char *getBinaryDir() const; /** * Add the file to the operating system most recently used files diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index 7fea0ce8a02..f2f1b26b8e5 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -50,10 +50,10 @@ GHOST_SystemSDL::~GHOST_SystemSDL() } GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -118,7 +118,7 @@ GHOST_TSuccess GHOST_SystemSDL::init() * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ -void GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemSDL::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { SDL_DisplayMode mode; SDL_GetDesktopDisplayMode(0, &mode); /* NOTE: always 0 display. */ @@ -126,7 +126,7 @@ void GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 height = mode.h; } -void GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemSDL::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { SDL_DisplayMode mode; SDL_GetCurrentDisplayMode(0, &mode); /* NOTE: always 0 display. */ @@ -134,7 +134,7 @@ void GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 height = mode.h; } -GHOST_TUns8 GHOST_SystemSDL::getNumDisplays() const +uint8_t GHOST_SystemSDL::getNumDisplays() const { return SDL_GetNumVideoDisplays(); } @@ -356,15 +356,15 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) int x_win, y_win; SDL_GetWindowPosition(sdl_win, &x_win, &y_win); - GHOST_TInt32 x_root = sdl_sub_evt.x + x_win; - GHOST_TInt32 y_root = sdl_sub_evt.y + y_win; + int32_t x_root = sdl_sub_evt.x + x_win; + int32_t y_root = sdl_sub_evt.y + y_win; #if 0 if (window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) { - GHOST_TInt32 x_new = x_root; - GHOST_TInt32 y_new = y_root; - GHOST_TInt32 x_accum, y_accum; + int32_t x_new = x_root; + int32_t y_new = y_root; + int32_t x_accum, y_accum; GHOST_Rect bounds; /* fallback to window bounds */ @@ -611,7 +611,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) } } -GHOST_TSuccess GHOST_SystemSDL::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const +GHOST_TSuccess GHOST_SystemSDL::getCursorPosition(int32_t &x, int32_t &y) const { int x_win, y_win; SDL_Window *win = SDL_GetMouseFocus(); @@ -625,7 +625,7 @@ GHOST_TSuccess GHOST_SystemSDL::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 return GHOST_kSuccess; } -GHOST_TSuccess GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemSDL::setCursorPosition(int32_t x, int32_t y) { int x_win, y_win; SDL_Window *win = SDL_GetMouseFocus(); @@ -668,14 +668,14 @@ bool GHOST_SystemSDL::processEvents(bool waitForEvent) GHOST_TimerManager *timerMgr = getTimerManager(); if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) { - GHOST_TUns64 next = timerMgr->nextFireTime(); + uint64_t next = timerMgr->nextFireTime(); if (next == GHOST_kFireTimeNever) { SDL_WaitEventTimeout(NULL, -1); // SleepTillEvent(m_display, -1); } else { - GHOST_TInt64 maxSleep = next - getMilliSeconds(); + int64_t maxSleep = next - getMilliSeconds(); if (maxSleep >= 0) { SDL_WaitEventTimeout(NULL, next - getMilliSeconds()); @@ -743,17 +743,17 @@ GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons &buttons) const return GHOST_kSuccess; } -GHOST_TUns8 *GHOST_SystemSDL::getClipboard(bool selection) const +char *GHOST_SystemSDL::getClipboard(bool selection) const { - return (GHOST_TUns8 *)SDL_GetClipboardText(); + return (char *)SDL_GetClipboardText(); } -void GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const +void GHOST_SystemSDL::putClipboard(const char *buffer, bool selection) const { SDL_SetClipboardText(buffer); } -GHOST_TUns64 GHOST_SystemSDL::getMilliSeconds() +uint64_t GHOST_SystemSDL::getMilliSeconds() { - return GHOST_TUns64(SDL_GetTicks()); /* NOTE: 32 -> 64bits. */ + return uint64_t(SDL_GetTicks()); /* NOTE: 32 -> 64bits. */ } diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h index 1c92762ea01..051bb6777b1 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.h +++ b/intern/ghost/intern/GHOST_SystemSDL.h @@ -56,21 +56,21 @@ class GHOST_SystemSDL : public GHOST_System { GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; - GHOST_TUns8 *getClipboard(bool selection) const; + char *getClipboard(bool selection) const; - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + void putClipboard(const char *buffer, bool selection) const; - GHOST_TUns64 getMilliSeconds(); + uint64_t getMilliSeconds(); - GHOST_TUns8 getNumDisplays() const; + uint8_t getNumDisplays() const; - GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const; - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + GHOST_TSuccess setCursorPosition(int32_t x, int32_t y); - void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const; - void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const; GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings); @@ -80,10 +80,10 @@ class GHOST_SystemSDL : public GHOST_System { GHOST_TSuccess init(); GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index f54a022f249..75a80de983d 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -47,12 +47,20 @@ #include <xkbcommon/xkbcommon.h> #include <fcntl.h> -#include <linux/input-event-codes.h> #include <sys/mman.h> #include <unistd.h> #include <cstring> +/* selected input event code defines from 'linux/input-event-codes.h' + * We include some of the button input event codes here, since the header is + * only available in more recent kernel versions. The event codes are used to + * to differentiate from which mouse button an event comes from. + */ +#define BTN_LEFT 0x110 +#define BTN_RIGHT 0x111 +#define BTN_MIDDLE 0x112 + struct buffer_t { void *data; size_t size; @@ -468,7 +476,7 @@ static const zwp_relative_pointer_v1_listener relative_pointer_listener = { static void dnd_events(const input_t *const input, const GHOST_TEventType event) { - const GHOST_TUns64 time = input->system->getMilliSeconds(); + const uint64_t time = input->system->getMilliSeconds(); GHOST_IWindow *const window = static_cast<GHOST_WindowWayland *>( wl_surface_get_user_data(input->focus_pointer)); for (const std::string &type : mime_preference_order) { @@ -718,10 +726,9 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic GHOST_TStringArray *flist = static_cast<GHOST_TStringArray *>( malloc(sizeof(GHOST_TStringArray))); flist->count = int(uris.size()); - flist->strings = static_cast<GHOST_TUns8 **>(malloc(uris.size() * sizeof(GHOST_TUns8 *))); + flist->strings = static_cast<uint8_t **>(malloc(uris.size() * sizeof(uint8_t *))); for (size_t i = 0; i < uris.size(); i++) { - flist->strings[i] = static_cast<GHOST_TUns8 *>( - malloc((uris[i].size() + 1) * sizeof(GHOST_TUns8))); + flist->strings[i] = static_cast<uint8_t *>(malloc((uris[i].size() + 1) * sizeof(uint8_t))); memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1); } GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>( @@ -1171,7 +1178,7 @@ static void keyboard_key(void *data, .key_data = key_data, }); - auto cb = [](GHOST_ITimerTask *task, GHOST_TUns64 /*time*/) { + auto cb = [](GHOST_ITimerTask *task, uint64_t /*time*/) { struct key_repeat_payload_t *payload = static_cast<key_repeat_payload_t *>( task->getUserData()); payload->system->pushEvent(new GHOST_EventKey(payload->system->getMilliSeconds(), @@ -1511,14 +1518,14 @@ GHOST_TSuccess GHOST_SystemWayland::getButtons(GHOST_Buttons &buttons) const return GHOST_kFailure; } -GHOST_TUns8 *GHOST_SystemWayland::getClipboard(bool /*selection*/) const +char *GHOST_SystemWayland::getClipboard(bool /*selection*/) const { - GHOST_TUns8 *clipboard = static_cast<GHOST_TUns8 *>(malloc((selection.size() + 1))); + char *clipboard = static_cast<char *>(malloc((selection.size() + 1))); memcpy(clipboard, selection.data(), selection.size() + 1); return clipboard; } -void GHOST_SystemWayland::putClipboard(GHOST_TInt8 *buffer, bool /*selection*/) const +void GHOST_SystemWayland::putClipboard(const char *buffer, bool /*selection*/) const { if (!d->data_device_manager || d->inputs.empty()) { return; @@ -1545,12 +1552,12 @@ void GHOST_SystemWayland::putClipboard(GHOST_TInt8 *buffer, bool /*selection*/) } } -GHOST_TUns8 GHOST_SystemWayland::getNumDisplays() const +uint8_t GHOST_SystemWayland::getNumDisplays() const { - return d ? GHOST_TUns8(d->outputs.size()) : 0; + return d ? uint8_t(d->outputs.size()) : 0; } -GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const +GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) const { if (!d->inputs.empty() && (d->inputs[0]->focus_pointer != nullptr)) { x = d->inputs[0]->x; @@ -1562,12 +1569,12 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(GHOST_TInt32 &x, GHOST_TIn } } -GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(GHOST_TInt32 /*x*/, GHOST_TInt32 /*y*/) +GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(int32_t /*x*/, int32_t /*y*/) { return GHOST_kFailure; } -void GHOST_SystemWayland::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemWayland::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { if (getNumDisplays() > 0) { /* We assume first output as main. */ @@ -1576,7 +1583,7 @@ void GHOST_SystemWayland::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TU } } -void GHOST_SystemWayland::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemWayland::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { getMainDisplayDimensions(width, height); } @@ -1640,10 +1647,10 @@ GHOST_TSuccess GHOST_SystemWayland::disposeContext(GHOST_IContext *context) } GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -1780,8 +1787,8 @@ GHOST_TSuccess GHOST_SystemWayland::hasCursorShape(GHOST_TStandardCursor cursorS return GHOST_TSuccess(cursors.count(cursorShape) && !cursors.at(cursorShape).empty()); } -GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, +GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index 3a08a0d3b16..9f02afb9d5a 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -59,29 +59,29 @@ class GHOST_SystemWayland : public GHOST_System { GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const override; - GHOST_TUns8 *getClipboard(bool selection) const override; + char *getClipboard(bool selection) const override; - void putClipboard(GHOST_TInt8 *buffer, bool selection) const override; + void putClipboard(const char *buffer, bool selection) const override; - GHOST_TUns8 getNumDisplays() const override; + uint8_t getNumDisplays() const override; - GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const override; + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const override; - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) override; + GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) override; - void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const override; + void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override; - void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const override; + void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override; GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override; GHOST_TSuccess disposeContext(GHOST_IContext *context) override; GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -107,8 +107,8 @@ class GHOST_SystemWayland : public GHOST_System { GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor cursorShape); - GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 0282340c071..4f5e957077d 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -169,21 +169,21 @@ GHOST_SystemWin32::~GHOST_SystemWin32() toggleConsole(1); } -GHOST_TUns64 GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const +uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const { // Calculate the time passed since system initialization. __int64 delta = (perf_ticks - m_start) * 1000; - GHOST_TUns64 t = (GHOST_TUns64)(delta / m_freq); + uint64_t t = (uint64_t)(delta / m_freq); return t; } -GHOST_TUns64 GHOST_SystemWin32::tickCountToMillis(__int64 ticks) const +uint64_t GHOST_SystemWin32::tickCountToMillis(__int64 ticks) const { return ticks - m_lfstart; } -GHOST_TUns64 GHOST_SystemWin32::getMilliSeconds() const +uint64_t GHOST_SystemWin32::getMilliSeconds() const { // Hardware does not support high resolution timers. We will use GetTickCount instead then. if (!m_hasPerformanceCounter) { @@ -197,31 +197,31 @@ GHOST_TUns64 GHOST_SystemWin32::getMilliSeconds() const return performanceCounterToMillis(count); } -GHOST_TUns8 GHOST_SystemWin32::getNumDisplays() const +uint8_t GHOST_SystemWin32::getNumDisplays() const { GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::getNumDisplays(): m_displayManager==0\n"); - GHOST_TUns8 numDisplays; + uint8_t numDisplays; m_displayManager->getNumDisplays(numDisplays); return numDisplays; } -void GHOST_SystemWin32::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemWin32::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { width = ::GetSystemMetrics(SM_CXSCREEN); height = ::GetSystemMetrics(SM_CYSCREEN); } -void GHOST_SystemWin32::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemWin32::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { width = ::GetSystemMetrics(SM_CXVIRTUALSCREEN); height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN); } GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -410,8 +410,8 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent) #if 1 ::Sleep(1); #else - GHOST_TUns64 next = timerMgr->nextFireTime(); - GHOST_TInt64 maxSleep = next - getMilliSeconds(); + uint64_t next = timerMgr->nextFireTime(); + int64_t maxSleep = next - getMilliSeconds(); if (next == GHOST_kFireTimeNever) { ::WaitMessage(); @@ -448,7 +448,7 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent) return hasEventHandled; } -GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const +GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(int32_t &x, int32_t &y) const { POINT point; if (::GetCursorPos(&point)) { @@ -459,7 +459,7 @@ GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt3 return GHOST_kFailure; } -GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(int32_t x, int32_t y) { if (!::GetActiveWindow()) return GHOST_kFailure; @@ -1029,7 +1029,7 @@ void GHOST_SystemWin32::processPointerEvent( case WM_POINTERUPDATE: /* Coalesced pointer events are reverse chronological order, reorder chronologically. * Only contiguous move events are coalesced. */ - for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) { + for (uint32_t i = pointerInfo.size(); i-- > 0;) { system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time, GHOST_kEventCursorMove, window, @@ -1079,7 +1079,7 @@ void GHOST_SystemWin32::processPointerEvent( GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window) { - GHOST_TInt32 x_screen, y_screen; + int32_t x_screen, y_screen; GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); if (window->getTabletData().Active != GHOST_kTabletModeNone) { @@ -1090,9 +1090,9 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind system->getCursorPosition(x_screen, y_screen); if (window->getCursorGrabModeIsWarp()) { - GHOST_TInt32 x_new = x_screen; - GHOST_TInt32 y_new = y_screen; - GHOST_TInt32 x_accum, y_accum; + int32_t x_new = x_screen; + int32_t y_new = y_screen; + int32_t x_accum, y_accum; GHOST_Rect bounds; /* Fallback to window bounds. */ @@ -1322,7 +1322,7 @@ void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax) bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw) { bool eventSent = false; - GHOST_TUns64 now = getMilliSeconds(); + uint64_t now = getMilliSeconds(); static bool firstEvent = true; if (firstEvent) { // determine exactly which device is plugged in @@ -1627,7 +1627,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, processPointerEvent(msg, window, wParam, lParam, eventHandled); break; case WM_POINTERLEAVE: { - GHOST_TUns32 pointerId = GET_POINTERID_WPARAM(wParam); + uint32_t pointerId = GET_POINTERID_WPARAM(wParam); POINTER_INFO pointerInfo; if (!GetPointerInfo(pointerId, &pointerInfo)) { break; @@ -2002,7 +2002,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, return lResult; } -GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const +char *GHOST_SystemWin32::getClipboard(bool selection) const { char *temp_buff; @@ -2026,7 +2026,7 @@ GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const GlobalUnlock(hData); CloseClipboard(); - return (GHOST_TUns8 *)temp_buff; + return temp_buff; } else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) { char *buffer; @@ -2052,14 +2052,14 @@ GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const GlobalUnlock(hData); CloseClipboard(); - return (GHOST_TUns8 *)temp_buff; + return temp_buff; } else { return NULL; } } -void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const +void GHOST_SystemWin32::putClipboard(const char *buffer, bool selection) const { if (selection) { return; diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 7dd61421d4c..6c786aedfb1 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -69,14 +69,14 @@ class GHOST_SystemWin32 : public GHOST_System { * system process. * \return The number of milliseconds since the start of the system process. */ - GHOST_TUns64 performanceCounterToMillis(__int64 perf_ticks) const; + uint64_t performanceCounterToMillis(__int64 perf_ticks) const; /** * This method converts system ticks into milliseconds since the start of the * system process. * \return The number of milliseconds since the start of the system process. */ - GHOST_TUns64 tickCountToMillis(__int64 ticks) const; + uint64_t tickCountToMillis(__int64 ticks) const; /** * Returns the system time. @@ -84,7 +84,7 @@ class GHOST_SystemWin32 : public GHOST_System { * This overloaded method uses the high frequency timer if available. * \return The number of milliseconds. */ - GHOST_TUns64 getMilliSeconds() const; + uint64_t getMilliSeconds() const; /*************************************************************************************** ** Display/window management functionality @@ -94,19 +94,19 @@ class GHOST_SystemWin32 : public GHOST_System { * Returns the number of displays on this system. * \return The number of displays. */ - GHOST_TUns8 getNumDisplays() const; + uint8_t getNumDisplays() const; /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ - void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const; /** * Returns the dimensions of all displays on this system. * \return The dimension of the main display. */ - void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const; /** * Create a new window. @@ -126,10 +126,10 @@ class GHOST_SystemWin32 : public GHOST_System { * \return The new window (or 0 if creation failed). */ GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -189,7 +189,7 @@ class GHOST_SystemWin32 : public GHOST_System { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const; /** * Updates the location of the cursor (location in screen coordinates). @@ -197,7 +197,7 @@ class GHOST_SystemWin32 : public GHOST_System { * \param y: The y-coordinate of the cursor. * \return Indication of success. */ - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + GHOST_TSuccess setCursorPosition(int32_t x, int32_t y); /*************************************************************************************** ** Access to mouse button and keyboard states. @@ -222,14 +222,14 @@ class GHOST_SystemWin32 : public GHOST_System { * \param selection: Used by X11 only. * \return Returns the Clipboard. */ - GHOST_TUns8 *getClipboard(bool selection) const; + char *getClipboard(bool selection) const; /** * Puts buffer to system clipboard. * \param selection: Used by X11 only. * \return No return. */ - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + void putClipboard(const char *buffer, bool selection) const; /** * Show a system message box diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index b8e221f5d0c..172fcbeb3de 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -186,7 +186,7 @@ GHOST_SystemX11::GHOST_SystemX11() : GHOST_System(), m_xkb_descr(NULL), m_start_ } /* Taking care not to overflow the `tv.tv_sec * 1000`. */ - m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000; + m_start_time = uint64_t(tv.tv_sec) * 1000 + tv.tv_usec / 1000; /* Use detectable auto-repeat, mac and windows also do this. */ int use_xkb; @@ -279,7 +279,7 @@ GHOST_TSuccess GHOST_SystemX11::init() return GHOST_kFailure; } -GHOST_TUns64 GHOST_SystemX11::getMilliSeconds() const +uint64_t GHOST_SystemX11::getMilliSeconds() const { timeval tv; if (gettimeofday(&tv, NULL) == -1) { @@ -287,19 +287,19 @@ GHOST_TUns64 GHOST_SystemX11::getMilliSeconds() const } /* Taking care not to overflow the tv.tv_sec * 1000 */ - return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; + return uint64_t(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; } -GHOST_TUns8 GHOST_SystemX11::getNumDisplays() const +uint8_t GHOST_SystemX11::getNumDisplays() const { - return GHOST_TUns8(1); + return uint8_t(1); } /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ -void GHOST_SystemX11::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { if (m_display) { /* NOTE(campbell): for this to work as documented, @@ -313,7 +313,7 @@ void GHOST_SystemX11::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ -void GHOST_SystemX11::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const +void GHOST_SystemX11::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { if (m_display) { width = DisplayWidth(m_display, DefaultScreen(m_display)); @@ -339,10 +339,10 @@ void GHOST_SystemX11::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 * \return The new window (or 0 if creation failed). */ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -570,7 +570,7 @@ GHOST_WindowX11 *GHOST_SystemX11::findGhostWindow(Window xwind) const return NULL; } -static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep) +static void SleepTillEvent(Display *display, int64_t maxSleep) { int fd = ConnectionNumber(display); fd_set fds; @@ -649,13 +649,13 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent) GHOST_TimerManager *timerMgr = getTimerManager(); if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) { - GHOST_TUns64 next = timerMgr->nextFireTime(); + uint64_t next = timerMgr->nextFireTime(); if (next == GHOST_kFireTimeNever) { SleepTillEvent(m_display, -1); } else { - GHOST_TInt64 maxSleep = next - getMilliSeconds(); + int64_t maxSleep = next - getMilliSeconds(); if (maxSleep >= 0) SleepTillEvent(m_display, next - getMilliSeconds()); @@ -965,9 +965,9 @@ void GHOST_SystemX11::processEvent(XEvent *xe) bool is_tablet = window->GetTabletData().Active != GHOST_kTabletModeNone; if (is_tablet == false && window->getCursorGrabModeIsWarp()) { - GHOST_TInt32 x_new = xme.x_root; - GHOST_TInt32 y_new = xme.y_root; - GHOST_TInt32 x_accum, y_accum; + int32_t x_new = xme.x_root; + int32_t y_new = xme.y_root; + int32_t x_accum, y_accum; GHOST_Rect bounds; /* fallback to window bounds */ @@ -1638,8 +1638,8 @@ GHOST_TSuccess GHOST_SystemX11::getButtons(GHOST_Buttons &buttons) const } static GHOST_TSuccess getCursorPosition_impl(Display *display, - GHOST_TInt32 &x, - GHOST_TInt32 &y, + int32_t &x, + int32_t &y, Window *child_return) { int rx, ry, wx, wy; @@ -1664,13 +1664,13 @@ static GHOST_TSuccess getCursorPosition_impl(Display *display, return GHOST_kSuccess; } -GHOST_TSuccess GHOST_SystemX11::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const +GHOST_TSuccess GHOST_SystemX11::getCursorPosition(int32_t &x, int32_t &y) const { Window child_return; return getCursorPosition_impl(m_display, x, y, &child_return); } -GHOST_TSuccess GHOST_SystemX11::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) +GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y) { /* This is a brute force move in screen coordinates @@ -2136,14 +2136,14 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt, return; } -GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const +char *GHOST_SystemX11::getClipboard(bool selection) const { Atom sseln; Atom target = m_atom.UTF8_STRING; Window owner; /* from xclip.c doOut() v0.11 */ - unsigned char *sel_buf; + char *sel_buf; unsigned long sel_len = 0; XEvent evt; unsigned int context = XCLIB_XCOUT_NONE; @@ -2162,13 +2162,13 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const owner = XGetSelectionOwner(m_display, sseln); if (owner == win) { if (sseln == m_atom.CLIPBOARD) { - sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1); - strcpy((char *)sel_buf, txt_cut_buffer); + sel_buf = (char *)malloc(strlen(txt_cut_buffer) + 1); + strcpy(sel_buf, txt_cut_buffer); return sel_buf; } else { - sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1); - strcpy((char *)sel_buf, txt_select_buffer); + sel_buf = (char *)malloc(strlen(txt_select_buffer) + 1); + strcpy(sel_buf, txt_select_buffer); return sel_buf; } } @@ -2187,7 +2187,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const } /* fetch the selection, or part of it */ - getClipboard_xcout(&evt, sseln, target, &sel_buf, &sel_len, &context); + getClipboard_xcout(&evt, sseln, target, (unsigned char **)&sel_buf, &sel_len, &context); if (restore_this_event) { restore_events.push_back(evt); @@ -2228,8 +2228,8 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const if (sel_len) { /* Only print the buffer out, and free it, if it's not empty. */ - unsigned char *tmp_data = (unsigned char *)malloc(sel_len + 1); - memcpy((char *)tmp_data, (char *)sel_buf, sel_len); + char *tmp_data = (char *)malloc(sel_len + 1); + memcpy(tmp_data, (char *)sel_buf, sel_len); tmp_data[sel_len] = '\0'; if (sseln == m_atom.STRING) @@ -2242,7 +2242,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const return NULL; } -void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const +void GHOST_SystemX11::putClipboard(const char *buffer, bool selection) const { Window m_window, owner; diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index ed5e945f69e..15ccde4a14b 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -98,25 +98,25 @@ class GHOST_SystemX11 : public GHOST_System { * Returns the number of milliseconds since the start of the system process. * \return The number of milliseconds. */ - GHOST_TUns64 getMilliSeconds() const; + uint64_t getMilliSeconds() const; /** * Returns the number of displays on this system. * \return The number of displays. */ - GHOST_TUns8 getNumDisplays() const; + uint8_t getNumDisplays() const; /** * Returns the dimensions of the main display on this system. * \return The dimension of the main display. */ - void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const; /** * Returns the dimensions of all displays on this system. * \return The dimension of the main display. */ - void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const; + void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const; /** * Create a new window. @@ -136,10 +136,10 @@ class GHOST_SystemX11 : public GHOST_System { * \return The new window (or 0 if creation failed). */ GHOST_IWindow *createWindow(const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, @@ -168,9 +168,9 @@ class GHOST_SystemX11 : public GHOST_System { */ bool processEvents(bool waitForEvent); - GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const; - GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); + GHOST_TSuccess setCursorPosition(int32_t x, int32_t y); /** * Returns the state of all modifier keys. @@ -222,14 +222,14 @@ class GHOST_SystemX11 : public GHOST_System { * \param selection: Get selection, X11 only feature. * \return Returns the Clipboard indicated by Flag. */ - GHOST_TUns8 *getClipboard(bool selection) const; + char *getClipboard(bool selection) const; /** * Puts buffer to system clipboard * \param buffer: The buffer to copy to the clipboard. * \param selection: Set the selection into the clipboard, X11 only feature. */ - void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + void putClipboard(const char *buffer, bool selection) const; /** * Show a system message box @@ -351,7 +351,7 @@ class GHOST_SystemX11 : public GHOST_System { std::vector<GHOST_WindowX11 *> m_dirty_windows; /** Start time at initialization. */ - GHOST_TUns64 m_start_time; + uint64_t m_start_time; /** A vector of keyboard key masks. */ char m_keyboard_vector[32]; diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp index 22f646320ce..195135f5f85 100644 --- a/intern/ghost/intern/GHOST_TimerManager.cpp +++ b/intern/ghost/intern/GHOST_TimerManager.cpp @@ -40,9 +40,9 @@ GHOST_TimerManager::~GHOST_TimerManager() disposeTimers(); } -GHOST_TUns32 GHOST_TimerManager::getNumTimers() +uint32_t GHOST_TimerManager::getNumTimers() { - return (GHOST_TUns32)m_timers.size(); + return (uint32_t)m_timers.size(); } bool GHOST_TimerManager::getTimerFound(GHOST_TimerTask *timer) @@ -81,13 +81,13 @@ GHOST_TSuccess GHOST_TimerManager::removeTimer(GHOST_TimerTask *timer) return success; } -GHOST_TUns64 GHOST_TimerManager::nextFireTime() +uint64_t GHOST_TimerManager::nextFireTime() { - GHOST_TUns64 smallest = GHOST_kFireTimeNever; + uint64_t smallest = GHOST_kFireTimeNever; TTimerVector::iterator iter; for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { - GHOST_TUns64 next = (*iter)->getNext(); + uint64_t next = (*iter)->getNext(); if (next < smallest) smallest = next; @@ -96,7 +96,7 @@ GHOST_TUns64 GHOST_TimerManager::nextFireTime() return smallest; } -bool GHOST_TimerManager::fireTimers(GHOST_TUns64 time) +bool GHOST_TimerManager::fireTimers(uint64_t time) { TTimerVector::iterator iter; bool anyProcessed = false; @@ -109,20 +109,20 @@ bool GHOST_TimerManager::fireTimers(GHOST_TUns64 time) return anyProcessed; } -bool GHOST_TimerManager::fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task) +bool GHOST_TimerManager::fireTimer(uint64_t time, GHOST_TimerTask *task) { - GHOST_TUns64 next = task->getNext(); + uint64_t next = task->getNext(); // Check if the timer should be fired if (time > next) { // Fire the timer GHOST_TimerProcPtr timerProc = task->getTimerProc(); - GHOST_TUns64 start = task->getStart(); + uint64_t start = task->getStart(); timerProc(task, time - start); // Update the time at which we will fire it again - GHOST_TUns64 interval = task->getInterval(); - GHOST_TUns64 numCalls = (next - start) / interval; + uint64_t interval = task->getInterval(); + uint64_t numCalls = (next - start) / interval; numCalls++; next = start + numCalls * interval; task->setNext(next); diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h index 3ca62202e5e..6261218a023 100644 --- a/intern/ghost/intern/GHOST_TimerManager.h +++ b/intern/ghost/intern/GHOST_TimerManager.h @@ -51,7 +51,7 @@ class GHOST_TimerManager { * Returns the number of timer tasks. * \return The number of events on the stack. */ - GHOST_TUns32 getNumTimers(); + uint32_t getNumTimers(); /** * Returns whether this timer task ins in our list. @@ -80,14 +80,14 @@ class GHOST_TimerManager { * \return The soonest time the next timer would fire, * or GHOST_kFireTimeNever if no timers exist. */ - GHOST_TUns64 nextFireTime(); + uint64_t nextFireTime(); /** * Checks all timer tasks to see if they are expired and fires them if needed. * \param time: The current time. * \return True if any timers were fired. */ - bool fireTimers(GHOST_TUns64 time); + bool fireTimers(uint64_t time); /** * Checks this timer task to see if they are expired and fires them if needed. @@ -95,7 +95,7 @@ class GHOST_TimerManager { * \param task: The timer task to check and optionally fire. * \return True if the timer fired. */ - bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task); + bool fireTimer(uint64_t time, GHOST_TimerTask *task); protected: /** diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h index 9c81d3d2637..e2812c6312b 100644 --- a/intern/ghost/intern/GHOST_TimerTask.h +++ b/intern/ghost/intern/GHOST_TimerTask.h @@ -38,8 +38,8 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * \param timerProc: The callback invoked when the interval expires. * \param userData: The timer user data. */ - GHOST_TimerTask(GHOST_TUns64 start, - GHOST_TUns64 interval, + GHOST_TimerTask(uint64_t start, + uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = NULL) : m_start(start), @@ -55,7 +55,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Returns the timer start time. * \return The timer start time. */ - inline GHOST_TUns64 getStart() const + inline uint64_t getStart() const { return m_start; } @@ -64,7 +64,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Changes the timer start time. * \param start: The timer start time. */ - void setStart(GHOST_TUns64 start) + void setStart(uint64_t start) { m_start = start; } @@ -73,7 +73,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Returns the timer interval. * \return The timer interval. */ - inline GHOST_TUns64 getInterval() const + inline uint64_t getInterval() const { return m_interval; } @@ -82,7 +82,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Changes the timer interval. * \param interval: The timer interval. */ - void setInterval(GHOST_TUns64 interval) + void setInterval(uint64_t interval) { m_interval = interval; } @@ -91,7 +91,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Returns the time the timerProc will be called. * \return The time the timerProc will be called. */ - inline GHOST_TUns64 getNext() const + inline uint64_t getNext() const { return m_next; } @@ -100,7 +100,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Changes the time the timerProc will be called. * \param next: The time the timerProc will be called. */ - void setNext(GHOST_TUns64 next) + void setNext(uint64_t next) { m_next = next; } @@ -145,7 +145,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Returns the auxiliary storage room. * \return The auxiliary storage room. */ - inline GHOST_TUns32 getAuxData() const + inline uint32_t getAuxData() const { return m_auxData; } @@ -154,20 +154,20 @@ class GHOST_TimerTask : public GHOST_ITimerTask { * Changes the auxiliary storage room. * \param auxData: The auxiliary storage room. */ - void setAuxData(GHOST_TUns32 auxData) + void setAuxData(uint32_t auxData) { m_auxData = auxData; } protected: /** The time the timer task was started. */ - GHOST_TUns64 m_start; + uint64_t m_start; /** The interval between calls. */ - GHOST_TUns64 m_interval; + uint64_t m_interval; /** The time the timerProc will be called. */ - GHOST_TUns64 m_next; + uint64_t m_next; /** The callback invoked when the timer expires. */ GHOST_TimerProcPtr m_timerProc; @@ -176,5 +176,5 @@ class GHOST_TimerTask : public GHOST_ITimerTask { GHOST_TUserDataPtr m_userData; /** Auxiliary storage room. */ - GHOST_TUns32 m_auxData; + uint32_t m_auxData; }; diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index ca19e251279..6009d7dbcfc 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -31,8 +31,8 @@ #include <assert.h> -GHOST_Window::GHOST_Window(GHOST_TUns32 width, - GHOST_TUns32 height, +GHOST_Window::GHOST_Window(uint32_t width, + uint32_t height, GHOST_TWindowState state, const bool wantStereoVisual, const bool /*exclusive*/) @@ -143,7 +143,7 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_TAxisFlag wrap_axis, GHOST_Rect *bounds, - GHOST_TInt32 mouse_ungrab_xy[2]) + int32_t mouse_ungrab_xy[2]) { if (m_cursorGrab == mode) return GHOST_kSuccess; @@ -192,13 +192,8 @@ GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape) } } -GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - bool canInvertColor) +GHOST_TSuccess GHOST_Window::setCustomCursorShape( + uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor) { if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor)) { m_cursorShape = GHOST_kStandardCursorCustom; diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 3542c6f2bcf..f061e07b3c8 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -48,8 +48,8 @@ class GHOST_Window : public GHOST_IWindow { * \param stereoVisual: Stereo visual for quad buffered stereo. * \param exclusive: Use to show the window ontop and ignore others (used full-screen). */ - GHOST_Window(GHOST_TUns32 width, - GHOST_TUns32 height, + GHOST_Window(uint32_t width, + uint32_t height, GHOST_TWindowState state, const bool wantStereoVisual = false, const bool exclusive = false); @@ -62,13 +62,13 @@ class GHOST_Window : public GHOST_IWindow { * virtual std::string getTitle() const = 0; * virtual void getWindowBounds(GHOST_Rect& bounds) const = 0; * virtual void getClientBounds(GHOST_Rect& bounds) const = 0; - * virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0; - * virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0; - * virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0; + * virtual GHOST_TSuccess setClientWidth(uint32_t width) = 0; + * virtual GHOST_TSuccess setClientHeight(uint32_t height) = 0; + * virtual GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) = 0; * virtual void screenToClient( - * GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0; + * int32_t inX, int32_t inY, int32_t& outX, int32_t& outY) const = 0; * virtual void clientToScreen( - * GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0; + * int32_t inX, int32_t inY, int32_t& outX, int32_t& outY) const = 0; * virtual GHOST_TWindowState getState() const = 0; * virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0; * virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0; @@ -126,8 +126,8 @@ class GHOST_Window : public GHOST_IWindow { * \param hotY: The Y coordinate of the cursor hot-spot. * \return Indication of success. */ - GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -142,9 +142,9 @@ class GHOST_Window : public GHOST_IWindow { inline GHOST_TGrabCursorMode getCursorGrabMode() const; inline bool getCursorGrabModeIsWarp() const; inline GHOST_TAxisFlag getCursorGrabAxis() const; - inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); + inline void getCursorGrabInitPos(int32_t &x, int32_t &y) const; + inline void getCursorGrabAccum(int32_t &x, int32_t &y) const; + inline void setCursorGrabAccum(int32_t x, int32_t y); /** * Shows or hides the cursor. @@ -161,7 +161,7 @@ class GHOST_Window : public GHOST_IWindow { GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_TAxisFlag wrap_axis, GHOST_Rect *bounds, - GHOST_TInt32 mouse_ungrab_xy[2]); + int32_t mouse_ungrab_xy[2]); /** * Gets the cursor grab region, if unset the window is used. @@ -292,14 +292,13 @@ class GHOST_Window : public GHOST_IWindow { * Returns the recommended DPI for this window. * \return The recommended DPI for this window. */ - virtual inline GHOST_TUns16 getDPIHint() + virtual inline uint16_t getDPIHint() { return 96; } #ifdef WITH_INPUT_IME - virtual void beginIME( - GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) + virtual void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed) { /* do nothing temporarily if not in windows */ } @@ -343,8 +342,8 @@ class GHOST_Window : public GHOST_IWindow { * Sets the cursor shape on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + virtual GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int szx, int szy, int hotX, @@ -369,10 +368,10 @@ class GHOST_Window : public GHOST_IWindow { GHOST_TAxisFlag m_cursorGrabAxis; /** Initial grab location. */ - GHOST_TInt32 m_cursorGrabInitPos[2]; + int32_t m_cursorGrabInitPos[2]; /** Accumulated offset from m_cursorGrabInitPos. */ - GHOST_TInt32 m_cursorGrabAccumPos[2]; + int32_t m_cursorGrabAccumPos[2]; /** Wrap the cursor within this region. */ GHOST_Rect m_cursorGrabBounds; @@ -396,9 +395,9 @@ class GHOST_Window : public GHOST_IWindow { bool m_wantStereoVisual; /** Full-screen width */ - GHOST_TUns32 m_fullScreenWidth; + uint32_t m_fullScreenWidth; /** Full-screen height */ - GHOST_TUns32 m_fullScreenHeight; + uint32_t m_fullScreenHeight; /* OSX only, retina screens */ float m_nativePixelSize; @@ -432,19 +431,19 @@ inline GHOST_TAxisFlag GHOST_Window::getCursorGrabAxis() const return m_cursorGrabAxis; } -inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const +inline void GHOST_Window::getCursorGrabInitPos(int32_t &x, int32_t &y) const { x = m_cursorGrabInitPos[0]; y = m_cursorGrabInitPos[1]; } -inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const +inline void GHOST_Window::getCursorGrabAccum(int32_t &x, int32_t &y) const { x = m_cursorGrabAccumPos[0]; y = m_cursorGrabAccumPos[1]; } -inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y) +inline void GHOST_Window::setCursorGrabAccum(int32_t x, int32_t y) { m_cursorGrabAccumPos[0] = x; m_cursorGrabAccumPos[1] = y; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 8ac1a78b32a..0fd70514ac6 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -60,10 +60,10 @@ class GHOST_WindowCocoa : public GHOST_Window { */ GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 bottom, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t bottom, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, @@ -119,20 +119,20 @@ class GHOST_WindowCocoa : public GHOST_Window { * Resizes client rectangle width. * \param width: The new width of the client area of the window. */ - GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + GHOST_TSuccess setClientWidth(uint32_t width); /** * Resizes client rectangle height. * \param height: The new height of the client area of the window. */ - GHOST_TSuccess setClientHeight(GHOST_TUns32 height); + GHOST_TSuccess setClientHeight(uint32_t height); /** * Resizes client rectangle. * \param width: The new width of the client area of the window. * \param height: The new height of the client area of the window. */ - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + GHOST_TSuccess setClientSize(uint32_t width, uint32_t height); /** * Returns the state of the window (normal, minimized, maximized). @@ -154,10 +154,7 @@ class GHOST_WindowCocoa : public GHOST_Window { * \param outX: The x-coordinate in the client rectangle. * \param outY: The y-coordinate in the client rectangle. */ - void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; /** * Converts a point in screen coordinates to client rectangle coordinates @@ -166,10 +163,7 @@ class GHOST_WindowCocoa : public GHOST_Window { * \param outX: The x-coordinate on the screen. * \param outY: The y-coordinate on the screen. */ - void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; /** * Converts a point in screen coordinates to client rectangle coordinates @@ -179,10 +173,7 @@ class GHOST_WindowCocoa : public GHOST_Window { * \param outX: The x-coordinate on the screen. * \param outY: The y-coordinate on the screen. */ - void clientToScreenIntern(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void clientToScreenIntern(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; /** * Converts a point in screen coordinates to client rectangle coordinates, @@ -192,10 +183,7 @@ class GHOST_WindowCocoa : public GHOST_Window { * \param outX: The x-coordinate on the screen. * \param outY: The y-coordinate on the screen. */ - void screenToClientIntern(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void screenToClientIntern(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; /** * Gets the screen the window is displayed in @@ -267,7 +255,7 @@ class GHOST_WindowCocoa : public GHOST_Window { } #ifdef WITH_INPUT_IME - void beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed); + void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed); void endIME(); #endif /* WITH_INPUT_IME */ @@ -307,8 +295,8 @@ class GHOST_WindowCocoa : public GHOST_Window { * Sets the cursor shape on the window using * native window system calls. */ - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -344,7 +332,7 @@ class GHOST_EventIME : public GHOST_Event { * \param type: The type of key event. * \param key: The key code of the key. */ - GHOST_EventIME(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata) + GHOST_EventIME(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata) : GHOST_Event(msec, type, window) { this->m_data = customdata; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index cea2969739c..0c3b3062126 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -284,10 +284,10 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 bottom, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t bottom, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual, @@ -570,13 +570,13 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect &bounds) const [pool drain]; } -GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) +GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(uint32_t width) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); - if (((GHOST_TUns32)cBnds.getWidth()) != width) { + if (((uint32_t)cBnds.getWidth()) != width) { NSSize size; size.width = width; size.height = cBnds.getHeight(); @@ -586,13 +586,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(uint32_t height) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); - if (((GHOST_TUns32)cBnds.getHeight()) != height) { + if (((uint32_t)cBnds.getHeight()) != height) { NSSize size; size.width = cBnds.getWidth(); size.height = height; @@ -602,14 +602,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowCocoa::setClientSize(uint32_t width, uint32_t height) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); - if ((((GHOST_TUns32)cBnds.getWidth()) != width) || - (((GHOST_TUns32)cBnds.getHeight()) != height)) { + if ((((uint32_t)cBnds.getWidth()) != width) || (((uint32_t)cBnds.getHeight()) != height)) { NSSize size; size.width = width; size.height = height; @@ -654,10 +653,10 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const return state; } -void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowCocoa::screenToClient(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid"); @@ -669,10 +668,10 @@ void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, outY = (cBnds.getHeight() - 1) - outY; } -void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowCocoa::clientToScreen(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid"); @@ -684,10 +683,10 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, clientToScreenIntern(inX, inY, outX, outY); } -void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowCocoa::screenToClientIntern(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { NSRect screenCoord; NSRect baseCoord; @@ -701,10 +700,10 @@ void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, outY = baseCoord.origin.y; } -void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowCocoa::clientToScreenIntern(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { NSRect screenCoord; NSRect baseCoord; @@ -1127,9 +1126,9 @@ GHOST_TSuccess GHOST_WindowCocoa::hasCursorShape(GHOST_TStandardCursor shape) return success; } -/* Reverse the bits in a GHOST_TUns8 */ +/* Reverse the bits in a uint8_t */ #if 0 -static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) +static uint8_t uns8ReverseBits(uint8_t ch) { ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); ch= ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC); @@ -1138,8 +1137,8 @@ static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) } #endif -/** Reverse the bits in a GHOST_TUns16 */ -static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt) +/** Reverse the bits in a uint16_t */ +static uint16_t uns16ReverseBits(uint16_t shrt) { shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA); shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC); @@ -1148,20 +1147,15 @@ static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt) return shrt; } -GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - bool canInvertColor) +GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape( + uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor) { int y, nbUns16; NSPoint hotSpotPoint; NSBitmapImageRep *cursorImageRep; NSImage *cursorImage; NSSize imSize; - GHOST_TUns16 *cursorBitmap; + uint16_t *cursorBitmap; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -1182,7 +1176,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap bytesPerRow:(sizex / 8 + (sizex % 8 > 0 ? 1 : 0)) bitsPerPixel:1]; - cursorBitmap = (GHOST_TUns16 *)[cursorImageRep bitmapData]; + cursorBitmap = (uint16_t *)[cursorImageRep bitmapData]; nbUns16 = [cursorImageRep bytesPerPlane] / 2; for (y = 0; y < nbUns16; y++) { @@ -1223,14 +1217,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap } #ifdef WITH_INPUT_IME -void GHOST_WindowCocoa::beginIME( - GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) +void GHOST_WindowCocoa::beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed) { if (m_openGLView) { - [m_openGLView beginIME:x y:y w:w h:h completed:(bool)completed]; + [m_openGLView beginIME:x y:y w:w h:h completed:completed]; } else { - [m_metalView beginIME:x y:y w:w h:h completed:(bool)completed]; + [m_metalView beginIME:x y:y w:w h:h completed:completed]; } } diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index aca06ba75b5..a3f9e2f0a13 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -36,10 +36,10 @@ class GHOST_WindowNULL : public GHOST_Window { GHOST_WindowNULL(GHOST_SystemNULL *system, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, const GHOST_IWindow *parentWindow, GHOST_TDrawingContextType type, @@ -66,8 +66,8 @@ class GHOST_WindowNULL : public GHOST_Window { { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -95,30 +95,24 @@ class GHOST_WindowNULL : public GHOST_Window { void getClientBounds(GHOST_Rect &bounds) const { /* nothing */ } - GHOST_TSuccess setClientWidth(GHOST_TUns32 width) + GHOST_TSuccess setClientWidth(uint32_t width) { return GHOST_kFailure; } - GHOST_TSuccess setClientHeight(GHOST_TUns32 height) + GHOST_TSuccess setClientHeight(uint32_t height) { return GHOST_kFailure; } - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) + GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) { return GHOST_kFailure; } - void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const { outX = inX; outY = inY; } - void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const { outX = inX; outY = inY; diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp index 56ae0deb341..fa1fcee2911 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.cpp +++ b/intern/ghost/intern/GHOST_WindowSDL.cpp @@ -28,10 +28,10 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual, @@ -175,7 +175,7 @@ void GHOST_WindowSDL::getClientBounds(GHOST_Rect &bounds) const bounds.m_b = y + h; } -GHOST_TSuccess GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width) +GHOST_TSuccess GHOST_WindowSDL::setClientWidth(uint32_t width) { int height; SDL_GetWindowSize(m_sdl_win, NULL, &height); @@ -183,7 +183,7 @@ GHOST_TSuccess GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width) return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowSDL::setClientHeight(uint32_t height) { int width; SDL_GetWindowSize(m_sdl_win, &width, NULL); @@ -191,16 +191,13 @@ GHOST_TSuccess GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height) return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowSDL::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowSDL::setClientSize(uint32_t width, uint32_t height) { SDL_SetWindowSize(m_sdl_win, width, height); return GHOST_kSuccess; } -void GHOST_WindowSDL::screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowSDL::screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const { /* XXXSDL_WEAK_ABS_COORDS */ int x_win, y_win; @@ -209,10 +206,7 @@ void GHOST_WindowSDL::screenToClient(GHOST_TInt32 inX, outX = inX - x_win; outY = inY - y_win; } -void GHOST_WindowSDL::clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowSDL::clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const { /* XXXSDL_WEAK_ABS_COORDS */ int x_win, y_win; @@ -622,13 +616,8 @@ GHOST_TSuccess GHOST_WindowSDL::hasCursorShape(GHOST_TStandardCursor shape) return (getStandardCursorShape(shape)) ? GHOST_kSuccess : GHOST_kFailure; } -GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - bool canInvertColor) +GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape( + uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor) { if (m_sdl_custom_cursor) { SDL_FreeCursor(m_sdl_custom_cursor); @@ -647,7 +636,7 @@ GHOST_TSuccess GHOST_WindowSDL::setWindowCursorVisibility(bool visible) return GHOST_kSuccess; } -GHOST_TUns16 GHOST_WindowSDL::getDPIHint() +uint16_t GHOST_WindowSDL::getDPIHint() { int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win); if (displayIndex < 0) { diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h index bfe07af1c70..d2eedecc506 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.h +++ b/intern/ghost/intern/GHOST_WindowSDL.h @@ -48,10 +48,10 @@ class GHOST_WindowSDL : public GHOST_Window { public: GHOST_WindowSDL(GHOST_SystemSDL *system, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, @@ -95,8 +95,8 @@ class GHOST_WindowSDL : public GHOST_Window { GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape); GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor shape); - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -109,21 +109,15 @@ class GHOST_WindowSDL : public GHOST_Window { std::string getTitle() const; - GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + GHOST_TSuccess setClientWidth(uint32_t width); - GHOST_TSuccess setClientHeight(GHOST_TUns32 height); + GHOST_TSuccess setClientHeight(uint32_t height); - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + GHOST_TSuccess setClientSize(uint32_t width, uint32_t height); - void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; - void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; GHOST_TSuccess setState(GHOST_TWindowState state); @@ -146,5 +140,5 @@ class GHOST_WindowSDL : public GHOST_Window { return GHOST_kFailure; } - GHOST_TUns16 getDPIHint(); + uint16_t getDPIHint(); }; diff --git a/intern/ghost/intern/GHOST_WindowViewCocoa.h b/intern/ghost/intern/GHOST_WindowViewCocoa.h index 2aaf1d56116..fa629528809 100644 --- a/intern/ghost/intern/GHOST_WindowViewCocoa.h +++ b/intern/ghost/intern/GHOST_WindowViewCocoa.h @@ -55,11 +55,7 @@ windowCocoa:(GHOST_WindowCocoa *)winCocoa; #ifdef WITH_INPUT_IME -- (void)beginIME:(GHOST_TInt32)x - y:(GHOST_TInt32)y - w:(GHOST_TInt32)w - h:(GHOST_TInt32)h - completed:(bool)completed; +- (void)beginIME:(int32_t)x y:(int32_t)y w:(int32_t)w h:(int32_t)h completed:(bool)completed; - (void)endIME; #endif @@ -439,18 +435,14 @@ [self checkImeEnabled]; } -- (void)setImeCandidateWinPos:(GHOST_TInt32)x y:(GHOST_TInt32)y w:(GHOST_TInt32)w h:(GHOST_TInt32)h +- (void)setImeCandidateWinPos:(int32_t)x y:(int32_t)y w:(int32_t)w h:(int32_t)h { - GHOST_TInt32 outX, outY; + int32_t outX, outY; associatedWindow->clientToScreen(x, y, outX, outY); ime.candidate_window_position = NSMakeRect((CGFloat)outX, (CGFloat)outY, (CGFloat)w, (CGFloat)h); } -- (void)beginIME:(GHOST_TInt32)x - y:(GHOST_TInt32)y - w:(GHOST_TInt32)w - h:(GHOST_TInt32)h - completed:(bool)completed +- (void)beginIME:(int32_t)x y:(int32_t)y w:(int32_t)w h:(int32_t)h completed:(bool)completed { ime.state_flag |= GHOST_IME_INPUT_FOCUSED; [self checkImeEnabled]; diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 5be7724fd86..d0c8cfb9e73 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -36,7 +36,7 @@ struct window_t { wl_surface *surface; // outputs on which the window is currently shown on std::unordered_set<const output_t *> outputs; - GHOST_TUns16 dpi = 0; + uint16_t dpi = 0; int scale = 1; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; @@ -205,10 +205,10 @@ GHOST_TSuccess GHOST_WindowWayland::hasCursorShape(GHOST_TStandardCursor cursorS GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, const char *title, - GHOST_TInt32 /*left*/, - GHOST_TInt32 /*top*/, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t /*left*/, + int32_t /*top*/, + uint32_t width, + uint32_t height, GHOST_TWindowState state, const GHOST_IWindow *parentWindow, GHOST_TDrawingContextType type, @@ -344,13 +344,8 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorShape(GHOST_TStandardCursor s return ok; } -GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizex, - int sizey, - int hotX, - int hotY, - bool canInvertColor) +GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape( + uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor) { return m_system->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor); } @@ -377,35 +372,35 @@ void GHOST_WindowWayland::getClientBounds(GHOST_Rect &bounds) const bounds.set(0, 0, w->width, w->height); } -GHOST_TSuccess GHOST_WindowWayland::setClientWidth(GHOST_TUns32 width) +GHOST_TSuccess GHOST_WindowWayland::setClientWidth(uint32_t width) { - return setClientSize(width, GHOST_TUns32(w->height)); + return setClientSize(width, uint32_t(w->height)); } -GHOST_TSuccess GHOST_WindowWayland::setClientHeight(GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowWayland::setClientHeight(uint32_t height) { - return setClientSize(GHOST_TUns32(w->width), height); + return setClientSize(uint32_t(w->width), height); } -GHOST_TSuccess GHOST_WindowWayland::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowWayland::setClientSize(uint32_t width, uint32_t height) { wl_egl_window_resize(w->egl_window, int(width), int(height), 0, 0); return GHOST_kSuccess; } -void GHOST_WindowWayland::screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowWayland::screenToClient(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { outX = inX; outY = inY; } -void GHOST_WindowWayland::clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowWayland::clientToScreen(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { outX = inX; outY = inY; @@ -426,7 +421,7 @@ GHOST_WindowWayland::~GHOST_WindowWayland() delete w; } -GHOST_TUns16 GHOST_WindowWayland::getDPIHint() +uint16_t GHOST_WindowWayland::getDPIHint() { return w->dpi; } diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index dbddc7c469e..6ffcf99b48c 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -39,10 +39,10 @@ class GHOST_WindowWayland : public GHOST_Window { GHOST_WindowWayland(GHOST_SystemWayland *system, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, const GHOST_IWindow *parentWindow, GHOST_TDrawingContextType type, @@ -52,7 +52,7 @@ class GHOST_WindowWayland : public GHOST_Window { ~GHOST_WindowWayland() override; - GHOST_TUns16 getDPIHint() override; + uint16_t getDPIHint() override; GHOST_TSuccess close(); @@ -77,8 +77,8 @@ class GHOST_WindowWayland : public GHOST_Window { GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) override; - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -93,21 +93,15 @@ class GHOST_WindowWayland : public GHOST_Window { void getClientBounds(GHOST_Rect &bounds) const override; - GHOST_TSuccess setClientWidth(GHOST_TUns32 width) override; + GHOST_TSuccess setClientWidth(uint32_t width) override; - GHOST_TSuccess setClientHeight(GHOST_TUns32 height) override; + GHOST_TSuccess setClientHeight(uint32_t height) override; - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) override; + GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) override; - void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const override; + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override; - void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const override; + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override; GHOST_TSuccess setWindowCursorVisibility(bool visible) override; diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 762ee6bc0eb..b5d0fd8e6db 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -56,10 +56,10 @@ __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, bool wantStereoVisual, @@ -354,12 +354,12 @@ void GHOST_WindowWin32::getClientBounds(GHOST_Rect &bounds) const } } -GHOST_TSuccess GHOST_WindowWin32::setClientWidth(GHOST_TUns32 width) +GHOST_TSuccess GHOST_WindowWin32::setClientWidth(uint32_t width) { GHOST_TSuccess success; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); - if (cBnds.getWidth() != (GHOST_TInt32)width) { + if (cBnds.getWidth() != (int32_t)width) { getWindowBounds(wBnds); int cx = wBnds.getWidth() + width - cBnds.getWidth(); int cy = wBnds.getHeight(); @@ -373,12 +373,12 @@ GHOST_TSuccess GHOST_WindowWin32::setClientWidth(GHOST_TUns32 width) return success; } -GHOST_TSuccess GHOST_WindowWin32::setClientHeight(GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowWin32::setClientHeight(uint32_t height) { GHOST_TSuccess success; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); - if (cBnds.getHeight() != (GHOST_TInt32)height) { + if (cBnds.getHeight() != (int32_t)height) { getWindowBounds(wBnds); int cx = wBnds.getWidth(); int cy = wBnds.getHeight() + height - cBnds.getHeight(); @@ -392,12 +392,12 @@ GHOST_TSuccess GHOST_WindowWin32::setClientHeight(GHOST_TUns32 height) return success; } -GHOST_TSuccess GHOST_WindowWin32::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowWin32::setClientSize(uint32_t width, uint32_t height) { GHOST_TSuccess success; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); - if ((cBnds.getWidth() != (GHOST_TInt32)width) || (cBnds.getHeight() != (GHOST_TInt32)height)) { + if ((cBnds.getWidth() != (int32_t)width) || (cBnds.getHeight() != (int32_t)height)) { getWindowBounds(wBnds); int cx = wBnds.getWidth() + width - cBnds.getWidth(); int cy = wBnds.getHeight() + height - cBnds.getHeight(); @@ -423,10 +423,10 @@ GHOST_TWindowState GHOST_WindowWin32::getState() const return GHOST_kWindowStateNormal; } -void GHOST_WindowWin32::screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowWin32::screenToClient(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { POINT point = {inX, inY}; ::ScreenToClient(m_hWnd, &point); @@ -434,10 +434,10 @@ void GHOST_WindowWin32::screenToClient(GHOST_TInt32 inX, outY = point.y; } -void GHOST_WindowWin32::clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowWin32::clientToScreen(int32_t inX, + int32_t inY, + int32_t &outX, + int32_t &outY) const { POINT point = {inX, inY}; ::ClientToScreen(m_hWnd, &point); @@ -666,7 +666,7 @@ HCURSOR GHOST_WindowWin32::getStandardCursor(GHOST_TStandardCursor shape) const // Convert GHOST cursor to Windows OEM cursor HANDLE cursor = NULL; HMODULE module = ::GetModuleHandle(0); - GHOST_TUns32 flags = LR_SHARED | LR_DEFAULTSIZE; + uint32_t flags = LR_SHARED | LR_DEFAULTSIZE; int cx = 0, cy = 0; switch (shape) { @@ -835,7 +835,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode /* use to generate a mouse move event, otherwise the last event * blender gets can be outside the screen causing menus not to show * properly unless the user moves the mouse */ - GHOST_TInt32 pos[2]; + int32_t pos[2]; m_system->getCursorPosition(pos[0], pos[1]); m_system->setCursorPosition(pos[0], pos[1]); } @@ -867,10 +867,10 @@ GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorSha GHOST_TSuccess GHOST_WindowWin32::getPointerInfo( std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam) { - GHOST_TInt32 pointerId = GET_POINTERID_WPARAM(wParam); - GHOST_TInt32 isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam); + int32_t pointerId = GET_POINTERID_WPARAM(wParam); + int32_t isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam); GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem(); - GHOST_TUns32 outCount = 0; + uint32_t outCount = 0; if (!(GetPointerPenInfoHistory(pointerId, &outCount, NULL))) { return GHOST_kFailure; @@ -883,7 +883,7 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo( return GHOST_kFailure; } - for (GHOST_TUns32 i = 0; i < outCount; i++) { + for (uint32_t i = 0; i < outCount; i++) { POINTER_INFO pointerApiInfo = pointerPenInfo[i].pointerInfo; // Obtain the basic information from the event outPointerInfo[i].pointerId = pointerId; @@ -964,7 +964,7 @@ void GHOST_WindowWin32::loadWintab(bool enable) /* Focus Wintab if cursor is inside this window. This ensures Wintab is enabled when the * tablet is used to change the Tablet API. */ - GHOST_TInt32 x, y; + int32_t x, y; if (m_system->getCursorPosition(x, y)) { GHOST_Rect rect; getClientBounds(rect); @@ -1012,7 +1012,7 @@ GHOST_TabletData GHOST_WindowWin32::getTabletData() } } -GHOST_TUns16 GHOST_WindowWin32::getDPIHint() +uint16_t GHOST_WindowWin32::getDPIHint() { if (m_user32) { GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow)::GetProcAddress( @@ -1026,8 +1026,8 @@ GHOST_TUns16 GHOST_WindowWin32::getDPIHint() return USER_DEFAULT_SCREEN_DPI; } -/** Reverse the bits in a GHOST_TUns8 */ -static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) +/** Reverse the bits in a uint8_t */ +static uint8_t uns8ReverseBits(uint8_t ch) { ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC); @@ -1036,8 +1036,8 @@ static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) } #if 0 /* UNUSED */ -/** Reverse the bits in a GHOST_TUns16 */ -static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt) +/** Reverse the bits in a uint16_t */ +static uint16_t uns16ReverseBits(uint16_t shrt) { shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA); shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC); @@ -1047,17 +1047,12 @@ static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt) } #endif -GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, - int sizeX, - int sizeY, - int hotX, - int hotY, - bool canInvertColor) +GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape( + uint8_t *bitmap, uint8_t *mask, int sizeX, int sizeY, int hotX, int hotY, bool canInvertColor) { - GHOST_TUns32 andData[32]; - GHOST_TUns32 xorData[32]; - GHOST_TUns32 fullBitRow, fullMaskRow; + uint32_t andData[32]; + uint32_t xorData[32]; + uint32_t fullBitRow, fullMaskRow; int x, y, cols; cols = sizeX / 8; /* Number of whole bytes per row (width of bitmap/mask). */ @@ -1115,10 +1110,9 @@ GHOST_TSuccess GHOST_WindowWin32::endProgressBar() } #ifdef WITH_INPUT_IME -void GHOST_WindowWin32::beginIME( - GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) +void GHOST_WindowWin32::beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed) { - m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed); + m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), completed); } void GHOST_WindowWin32::endIME() diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 119092a001a..40a658bf88b 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -47,11 +47,11 @@ typedef BOOL(API *GHOST_WIN32_AdjustWindowRectExForDpi)( LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi); struct GHOST_PointerInfoWin32 { - GHOST_TInt32 pointerId; - GHOST_TInt32 isPrimary; + int32_t pointerId; + int32_t isPrimary; GHOST_TButtonMask buttonMask; POINT pixelLocation; - GHOST_TUns64 time; + uint64_t time; GHOST_TabletData tabletData; }; @@ -83,10 +83,10 @@ class GHOST_WindowWin32 : public GHOST_Window { */ GHOST_WindowWin32(GHOST_SystemWin32 *system, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, bool wantStereoVisual = false, @@ -152,20 +152,20 @@ class GHOST_WindowWin32 : public GHOST_Window { * Resizes client rectangle width. * \param width: The new width of the client area of the window. */ - GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + GHOST_TSuccess setClientWidth(uint32_t width); /** * Resizes client rectangle height. * \param height: The new height of the client area of the window. */ - GHOST_TSuccess setClientHeight(GHOST_TUns32 height); + GHOST_TSuccess setClientHeight(uint32_t height); /** * Resizes client rectangle. * \param width: The new width of the client area of the window. * \param height: The new height of the client area of the window. */ - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + GHOST_TSuccess setClientSize(uint32_t width, uint32_t height); /** * Returns the state of the window (normal, minimized, maximized). @@ -180,10 +180,7 @@ class GHOST_WindowWin32 : public GHOST_Window { * \param outX: The x-coordinate in the client rectangle. * \param outY: The y-coordinate in the client rectangle. */ - void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; /** * Converts a point in screen coordinates to client rectangle coordinates @@ -192,10 +189,7 @@ class GHOST_WindowWin32 : public GHOST_Window { * \param outX: The x-coordinate on the screen. * \param outY: The y-coordinate on the screen. */ - void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; /** * Sets the state of the window (normal, minimized, maximized). @@ -309,7 +303,7 @@ class GHOST_WindowWin32 : public GHOST_Window { return GHOST_kFailure; } - GHOST_TUns16 getDPIHint() override; + uint16_t getDPIHint() override; /** True if the mouse is either over or captured by the window. */ bool m_mousePresent; @@ -323,7 +317,7 @@ class GHOST_WindowWin32 : public GHOST_Window { return &m_imeInput; } - void beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed); + void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed); void endIME(); #endif /* WITH_INPUT_IME */ @@ -359,8 +353,8 @@ class GHOST_WindowWin32 : public GHOST_Window { * Sets the cursor shape on the window using * native window system calls. */ - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index ea798441adb..0ade7a52891 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -213,10 +213,10 @@ static XVisualInfo *x11_visualinfo_from_glx(Display *display, GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system, Display *display, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_WindowX11 *parentWindow, GHOST_TDrawingContextType type, @@ -622,7 +622,7 @@ void GHOST_WindowX11::getClientBounds(GHOST_Rect &bounds) const Window root_return; int x_return, y_return; unsigned int w_return, h_return, border_w_return, depth_return; - GHOST_TInt32 screen_x, screen_y; + int32_t screen_x, screen_y; XGetGeometry(m_display, m_window, @@ -642,7 +642,7 @@ void GHOST_WindowX11::getClientBounds(GHOST_Rect &bounds) const bounds.m_b = bounds.m_t + h_return; } -GHOST_TSuccess GHOST_WindowX11::setClientWidth(GHOST_TUns32 width) +GHOST_TSuccess GHOST_WindowX11::setClientWidth(uint32_t width) { XWindowChanges values; unsigned int value_mask = CWWidth; @@ -652,7 +652,7 @@ GHOST_TSuccess GHOST_WindowX11::setClientWidth(GHOST_TUns32 width) return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowX11::setClientHeight(GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowX11::setClientHeight(uint32_t height) { XWindowChanges values; unsigned int value_mask = CWHeight; @@ -661,7 +661,7 @@ GHOST_TSuccess GHOST_WindowX11::setClientHeight(GHOST_TUns32 height) return GHOST_kSuccess; } -GHOST_TSuccess GHOST_WindowX11::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) +GHOST_TSuccess GHOST_WindowX11::setClientSize(uint32_t width, uint32_t height) { XWindowChanges values; unsigned int value_mask = CWWidth | CWHeight; @@ -671,10 +671,7 @@ GHOST_TSuccess GHOST_WindowX11::setClientSize(GHOST_TUns32 width, GHOST_TUns32 h return GHOST_kSuccess; } -void GHOST_WindowX11::screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowX11::screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const { /* This is correct! */ @@ -687,10 +684,7 @@ void GHOST_WindowX11::screenToClient(GHOST_TInt32 inX, outY = ay; } -void GHOST_WindowX11::clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const +void GHOST_WindowX11::clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const { int ax, ay; Window temp; @@ -1590,8 +1584,8 @@ GHOST_TSuccess GHOST_WindowX11::hasCursorShape(GHOST_TStandardCursor shape) return getStandardCursor(shape, xcursor); } -GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, +GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, @@ -1679,7 +1673,7 @@ GHOST_TSuccess GHOST_WindowX11::endFullScreen() const return GHOST_kSuccess; } -GHOST_TUns16 GHOST_WindowX11::getDPIHint() +uint16_t GHOST_WindowX11::getDPIHint() { /* Try to read DPI setting set using xrdb */ char *resMan = XResourceManagerString(m_display); diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 01699e9d1ce..9f3d48dfafc 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -68,10 +68,10 @@ class GHOST_WindowX11 : public GHOST_Window { GHOST_WindowX11(GHOST_SystemX11 *system, Display *display, const char *title, - GHOST_TInt32 left, - GHOST_TInt32 top, - GHOST_TUns32 width, - GHOST_TUns32 height, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, GHOST_TWindowState state, GHOST_WindowX11 *parentWindow, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, @@ -93,21 +93,15 @@ class GHOST_WindowX11 : public GHOST_Window { bool isDialog() const; - GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + GHOST_TSuccess setClientWidth(uint32_t width); - GHOST_TSuccess setClientHeight(GHOST_TUns32 height); + GHOST_TSuccess setClientHeight(uint32_t height); - GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + GHOST_TSuccess setClientSize(uint32_t width, uint32_t height); - void screenToClient(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; - void clientToScreen(GHOST_TInt32 inX, - GHOST_TInt32 inY, - GHOST_TInt32 &outX, - GHOST_TInt32 &outY) const; + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const; GHOST_TWindowState getState() const; @@ -182,7 +176,7 @@ class GHOST_WindowX11 : public GHOST_Window { GHOST_TSuccess setDialogHints(GHOST_WindowX11 *parentWindow); - GHOST_TUns16 getDPIHint(); + uint16_t getDPIHint(); protected: /** @@ -216,8 +210,8 @@ class GHOST_WindowX11 : public GHOST_Window { * Sets the cursor shape on the window using * native window system calls (Arbitrary size/color). */ - GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, - GHOST_TUns8 *mask, + GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, + uint8_t *mask, int sizex, int sizey, int hotX, diff --git a/intern/ghost/intern/GHOST_Wintab.h b/intern/ghost/intern/GHOST_Wintab.h index 75017aa67d9..443c726d270 100644 --- a/intern/ghost/intern/GHOST_Wintab.h +++ b/intern/ghost/intern/GHOST_Wintab.h @@ -56,10 +56,10 @@ typedef std::unique_ptr<std::remove_pointer_t<HMODULE>, decltype(&::FreeLibrary) typedef std::unique_ptr<std::remove_pointer_t<HCTX>, GHOST_WIN32_WTClose> unique_hctx; struct GHOST_WintabInfoWin32 { - GHOST_TInt32 x, y; + int32_t x, y; GHOST_TEventType type; GHOST_TButtonMask button; - GHOST_TUns64 time; + uint64_t time; GHOST_TabletData tabletData; }; @@ -178,7 +178,7 @@ class GHOST_Wintab { bool m_focused = false; /** Pressed button map. */ - GHOST_TUns8 m_buttons = 0; + uint8_t m_buttons = 0; /** Range of a coordinate space. */ struct Range { diff --git a/intern/ghost/intern/GHOST_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp index b10e001df47..9c4f7fbc7d8 100644 --- a/intern/ghost/intern/GHOST_XrAction.cpp +++ b/intern/ghost/intern/GHOST_XrAction.cpp @@ -329,7 +329,7 @@ void GHOST_XrAction::updateState(XrSession session, void GHOST_XrAction::applyHapticFeedback(XrSession session, const char *action_name, - const GHOST_TInt64 &duration, + const int64_t &duration, const float &frequency, const float &litude) { diff --git a/intern/ghost/intern/GHOST_XrAction.h b/intern/ghost/intern/GHOST_XrAction.h index bdc6cafb4a9..32445c616bd 100644 --- a/intern/ghost/intern/GHOST_XrAction.h +++ b/intern/ghost/intern/GHOST_XrAction.h @@ -91,7 +91,7 @@ class GHOST_XrAction { const XrTime &predicted_display_time); void applyHapticFeedback(XrSession session, const char *action_name, - const GHOST_TInt64 &duration, + const int64_t &duration, const float &frequency, const float &litude); void stopHapticFeedback(XrSession session, const char *action_name); diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp index a7438fae13c..35280e77e22 100644 --- a/intern/ghost/intern/GHOST_XrSession.cpp +++ b/intern/ghost/intern/GHOST_XrSession.cpp @@ -772,7 +772,7 @@ bool GHOST_XrSession::syncActions(const char *action_set_name) bool GHOST_XrSession::applyHapticAction(const char *action_set_name, const char *action_name, - const GHOST_TInt64 &duration, + const int64_t &duration, const float &frequency, const float &litude) { diff --git a/intern/ghost/intern/GHOST_XrSession.h b/intern/ghost/intern/GHOST_XrSession.h index a2d3cf2e385..c871b98da46 100644 --- a/intern/ghost/intern/GHOST_XrSession.h +++ b/intern/ghost/intern/GHOST_XrSession.h @@ -81,7 +81,7 @@ class GHOST_XrSession { bool syncActions(const char *action_set_name = nullptr); bool applyHapticAction(const char *action_set_name, const char *action_name, - const GHOST_TInt64 &duration, + const int64_t &duration, const float &frequency, const float &litude); void stopHapticAction(const char *action_set_name, const char *action_name); diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c index 1867218ec65..3257c42118e 100644 --- a/intern/ghost/test/gears/GHOST_C-Test.c +++ b/intern/ghost/test/gears/GHOST_C-Test.c @@ -46,7 +46,7 @@ # include <GL/gl.h> #endif /* defined(WIN32) || defined(__APPLE__) */ -static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time); +static void gearsTimerProc(GHOST_TimerTaskHandle task, uint64_t time); int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData); static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; @@ -60,7 +60,7 @@ static GHOST_WindowHandle sFullScreenWindow = NULL; static GHOST_TimerTaskHandle sTestTimer; static GHOST_TimerTaskHandle sGearsTimer; -static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) +static void testTimerProc(GHOST_TimerTaskHandle task, uint64_t time) { printf("timer1, time=%d\n", (int)time); } @@ -501,7 +501,7 @@ int main(int argc, char **argv) return 0; } -static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time) +static void gearsTimerProc(GHOST_TimerTaskHandle hTask, uint64_t time) { GHOST_WindowHandle hWindow = NULL; fAngle += 2.0; diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp index c9c497aacb4..c1cb5f29e2e 100644 --- a/intern/ghost/test/gears/GHOST_Test.cpp +++ b/intern/ghost/test/gears/GHOST_Test.cpp @@ -54,7 +54,7 @@ static bool nVidiaWindows; // very dirty but hey, it's for testing only -static void gearsTimerProc(GHOST_ITimerTask *task, GHOST_TUns64 time); +static void gearsTimerProc(GHOST_ITimerTask *task, uint64_t time); static class Application *fApp; static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; @@ -71,7 +71,7 @@ void StereoProjection(float left, float dist, float eye); -static void testTimerProc(GHOST_ITimerTask * /*task*/, GHOST_TUns64 time) +static void testTimerProc(GHOST_ITimerTask * /*task*/, uint64_t time) { std::cout << "timer1, time=" << (int)time << "\n"; } @@ -345,7 +345,7 @@ void StereoProjection(float left, float zero_plane, float dist, float eye) -/* Perform the perspective projection for one eye's subfield. +/* Perform the perspective projection for one eye's sub-field. * The projection is in the direction of the negative z axis. * * -6.0, 6.0, -4.8, 4.8, @@ -365,8 +365,8 @@ void StereoProjection(float left, * of zero parallax. * * -0.31 - * eye = half the eye separation; positive for the right eye subfield, - * negative for the left eye subfield. + * eye = half the eye separation; positive for the right eye sub-field, + * negative for the left eye sub-field. */ { float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw, dx, dy, n_over_d; @@ -392,8 +392,7 @@ void StereoProjection(float left, glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far); glTranslatef(-xmid - eye, -ymid, -zero_plane - dist); - return; -} /* stereoproj */ +} class Application : public GHOST_IEventConsumer { public: @@ -731,7 +730,7 @@ int main(int /*argc*/, char ** /*argv*/) return 0; } -static void gearsTimerProc(GHOST_ITimerTask *task, GHOST_TUns64 /*time*/) +static void gearsTimerProc(GHOST_ITimerTask *task, uint64_t /*time*/) { fAngle += 2.0; view_roty += 1.0; diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c index 788c0221753..44ea07bd880 100644 --- a/intern/ghost/test/multitest/EventToBuf.c +++ b/intern/ghost/test/multitest/EventToBuf.c @@ -203,7 +203,7 @@ static char *keytype_to_string(GHOST_TKey key) void event_to_buf(GHOST_EventHandle evt, char buf[128]) { GHOST_TEventType type = GHOST_GetEventType(evt); - double time = (double)((GHOST_TInt64)GHOST_GetEventTime(evt)) / 1000; + double time = (double)((int64_t)GHOST_GetEventTime(evt)) / 1000; GHOST_WindowHandle win = GHOST_GetEventWindow(evt); void *data = GHOST_GetEventData(evt); char *pos = buf; diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c index ccbbbceb5b6..0e6602d9510 100644 --- a/intern/ghost/test/multitest/MultiTest.c +++ b/intern/ghost/test/multitest/MultiTest.c @@ -302,12 +302,12 @@ static void mainwindow_handle(void *priv, GHOST_EventHandle evt) /**/ -static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) +static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, uint64_t time) { MainWindow *mw = GHOST_GetTimerTaskUserData(task); char buf[64]; - sprintf(buf, "timer: %6.2f", (double)((GHOST_TInt64)time) / 1000); + sprintf(buf, "timer: %6.2f", (double)((int64_t)time) / 1000); mainwindow_log(mw, buf); } @@ -570,7 +570,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app) { GHOST_GLSettings glSettings = {0}; GHOST_SystemHandle sys = multitestapp_get_system(app); - GHOST_TUns32 screensize[2]; + uint32_t screensize[2]; GHOST_WindowHandle win; GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]); @@ -701,11 +701,11 @@ static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press) } } -static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time) +static void extrawindow_spin_cursor(ExtraWindow *ew, uint64_t time) { - GHOST_TUns8 bitmap[16][2]; - GHOST_TUns8 mask[16][2]; - double ftime = (double)((GHOST_TInt64)time) / 1000; + uint8_t bitmap[16][2]; + uint8_t mask[16][2]; + double ftime = (double)((int64_t)time) / 1000; float angle = fmod(ftime, 1.0) * 3.1415 * 2; int i; diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h index aa956150484..e4bd3d533a3 100644 --- a/intern/guardedalloc/intern/mallocn_intern.h +++ b/intern/guardedalloc/intern/mallocn_intern.h @@ -53,14 +53,8 @@ size_t malloc_usable_size(void *ptr); # undef USE_MALLOC_USABLE_SIZE #endif -/* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */ -#if defined(WIN64) -# define SIZET_FORMAT "%I64u" -# define SIZET_ARG(a) ((unsigned long long)(a)) -#else -# define SIZET_FORMAT "%lu" -# define SIZET_ARG(a) ((unsigned long)(a)) -#endif +#define SIZET_FORMAT "%zu" +#define SIZET_ARG(a) ((size_t)(a)) #define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3) diff --git a/intern/libmv/libmv/numeric/numeric.h b/intern/libmv/libmv/numeric/numeric.h index e3d44226338..e3ebdb5a4bb 100644 --- a/intern/libmv/libmv/numeric/numeric.h +++ b/intern/libmv/libmv/numeric/numeric.h @@ -43,7 +43,7 @@ inline void sincos(double x, double* sinx, double* cosx) { # endif #endif // !__MINGW64__ -#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__) +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) inline long lround(double d) { return (long)(d > 0 ? d + 0.5 : ceil(d - 0.5)); } diff --git a/intern/libmv/libmv/tracking/retrack_region_tracker.cc b/intern/libmv/libmv/tracking/retrack_region_tracker.cc index 9152078053c..124a032cdff 100644 --- a/intern/libmv/libmv/tracking/retrack_region_tracker.cc +++ b/intern/libmv/libmv/tracking/retrack_region_tracker.cc @@ -37,7 +37,7 @@ bool RetrackRegionTracker::Track(const FloatImage& image1, } // Now track x2 and y2 backward, to get xx1 and yy1 which, if the track is // good, should match x1 and y1 (but may not if the track is bad). - double xx1 = *x2, yy1 = *x2; + double xx1 = *x2, yy1 = *y2; if (!tracker_->Track(image2, image1, *x2, *y2, &xx1, &yy1)) { return false; } diff --git a/release/scripts/freestyle/modules/freestyle/shaders.py b/release/scripts/freestyle/modules/freestyle/shaders.py index 28b8aa9b23e..95e1c873657 100644 --- a/release/scripts/freestyle/modules/freestyle/shaders.py +++ b/release/scripts/freestyle/modules/freestyle/shaders.py @@ -1153,11 +1153,9 @@ class RoundCapShader(StrokeShader): return # calculate the number of additional vertices to form caps thickness_beg = sum(stroke[0].attribute.thickness) - caplen_beg = thickness_beg / 2.0 nverts_beg = max(5, int(thickness_beg)) thickness_end = sum(stroke[-1].attribute.thickness) - caplen_end = (thickness_end) / 2.0 nverts_end = max(5, int(thickness_end)) # adjust the total number of stroke vertices @@ -1169,7 +1167,7 @@ class RoundCapShader(StrokeShader): # reshape the cap at the beginning of the stroke q, attr = buffer[1] p, attr = buffer[0] - direction = (p - q).normalized() * caplen_beg + direction = (p - q).normalized() * thickness_beg n = 1.0 / nverts_beg R, L = attr.thickness for t, svert in zip(range(nverts_beg, 0, -1), stroke): @@ -1180,7 +1178,7 @@ class RoundCapShader(StrokeShader): # reshape the cap at the end of the stroke q, attr = buffer[-2] p, attr = buffer[-1] - direction = (p - q).normalized() * caplen_beg + direction = (p - q).normalized() * thickness_end n = 1.0 / nverts_end R, L = attr.thickness for t, svert in zip(range(nverts_end, 0, -1), reversed(stroke)): diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index f63b6990cdd..fda93682dc5 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -781,7 +781,6 @@ class I18nMessages: print("Could not import bpy, find_best_messages_matches must be run from whithin Blender.") return - # Build helper mappings. # Note it's user responsibility to know when to invalidate (and hence force rebuild) this cache! if self._reverse_cache is None: diff --git a/release/scripts/modules/bl_i18n_utils/utils_cli.py b/release/scripts/modules/bl_i18n_utils/utils_cli.py index d3750d5e9a4..e18491fa042 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_cli.py +++ b/release/scripts/modules/bl_i18n_utils/utils_cli.py @@ -140,6 +140,7 @@ def main(): args.func(args=args, settings=settings) + if __name__ == "__main__": print("\n\n *** Running {} *** \n".format(__file__)) main() diff --git a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py index aff1108568b..26f38cf09fc 100644 --- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py +++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py @@ -449,6 +449,5 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True): ) kmi.properties.skip_depressed = True - wm.keyconfigs.update() return keymap diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py index 51ea53c0eba..17577a9a9f2 100644 --- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py +++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py @@ -37,6 +37,7 @@ OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'} def ids_nolib(bids): return (bid for bid in bids if not bid.library) + def ids_nolib_with_preview(bids): return (bid for bid in bids if (not bid.library and bid.preview)) diff --git a/release/scripts/modules/bl_rna_utils/data_path.py b/release/scripts/modules/bl_rna_utils/data_path.py index 42942b7a295..439dfcae12a 100644 --- a/release/scripts/modules/bl_rna_utils/data_path.py +++ b/release/scripts/modules/bl_rna_utils/data_path.py @@ -23,6 +23,7 @@ __all__ = ( "decompose_data_path", ) + class _TokenizeDataPath: """ Class to split up tokens of a data-path. diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index e6c7bca3e3c..58b20d9e3c8 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -155,6 +155,7 @@ def _test_import(module_name, loaded_modules): # This supports the case of loading a new preferences file which may reset scripts path. _sys_path_ensure_paths = set() + def _sys_path_ensure_prepend(path): if path not in _sys.path: _sys.path.insert(0, path) diff --git a/release/scripts/modules/bpy_extras/asset_utils.py b/release/scripts/modules/bpy_extras/asset_utils.py index 1656c21a137..e41eeeed4fa 100644 --- a/release/scripts/modules/bpy_extras/asset_utils.py +++ b/release/scripts/modules/bpy_extras/asset_utils.py @@ -31,6 +31,7 @@ __all__ = ( "SpaceAssetInfo", ) + class SpaceAssetInfo: @classmethod def is_asset_browser(cls, space_data: bpy.types.Space): @@ -46,6 +47,7 @@ class SpaceAssetInfo: active_file = context.active_file return active_file.asset_data if active_file else None + class AssetBrowserPanel: bl_space_type = 'FILE_BROWSER' @@ -53,6 +55,7 @@ class AssetBrowserPanel: def poll(cls, context): return SpaceAssetInfo.is_asset_browser_poll(context) + class AssetMetaDataPanel: bl_space_type = 'FILE_BROWSER' bl_region_type = 'TOOL_PROPS' diff --git a/release/scripts/modules/bpy_extras/node_shader_utils.py b/release/scripts/modules/bpy_extras/node_shader_utils.py index 54124fd4ca6..e37c1a17152 100644 --- a/release/scripts/modules/bpy_extras/node_shader_utils.py +++ b/release/scripts/modules/bpy_extras/node_shader_utils.py @@ -681,7 +681,10 @@ class ShaderImageTextureWrapper(): tree = self.owner_shader.material.node_tree node_image = tree.nodes.new(type='ShaderNodeTexImage') - self.owner_shader._grid_to_location(-1, 0 + self.grid_row_diff, dst_node=node_image, ref_node=self.node_dst) + self.owner_shader._grid_to_location( + -1, 0 + self.grid_row_diff, + dst_node=node_image, ref_node=self.node_dst, + ) tree.links.new(node_image.outputs["Alpha" if self.use_alpha else "Color"], self.socket_dst) if self.use_alpha: @@ -778,7 +781,7 @@ class ShaderImageTextureWrapper(): socket_dst = self.node_image.inputs["Vector"] # If not already existing, we need to create texcoords -> mapping link (from UV). socket_src = (socket_dst.links[0].from_socket if socket_dst.is_linked - else self.owner_shader.node_texcoords.outputs['UV']) + else self.owner_shader.node_texcoords.outputs['UV']) tree = self.owner_shader.material.node_tree node_mapping = tree.nodes.new(type='ShaderNodeMapping') diff --git a/release/scripts/modules/console/complete_calltip.py b/release/scripts/modules/console/complete_calltip.py index 706af67905b..60daa1d2045 100644 --- a/release/scripts/modules/console/complete_calltip.py +++ b/release/scripts/modules/console/complete_calltip.py @@ -41,7 +41,7 @@ RE_DEF_COMPLETE = re.compile( # allow empty string '''|)''' # allow opening bracket(s) - '''(?:\(|\s)*)$''') + r'''(?:\(|\s)*)$''') def reduce_newlines(text): diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 7f1039a975b..0af7493ed47 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -4113,7 +4113,7 @@ def km_pose(params): ("pose.bone_layers", {"type": 'M', "value": 'PRESS'}, None), ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True}, None), ("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS'}, None), - ("anim.keyframe_delete", {"type": 'I', "value": 'PRESS', "alt": True}, None), + ("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True}, None), ("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), ("poselib.browse_interactive", {"type": 'L', "value": 'PRESS', "alt": True}, None), ("poselib.pose_add", {"type": 'L', "value": 'PRESS', "shift": True}, None), @@ -4185,7 +4185,7 @@ def km_object_mode(params): ("wm.context_toggle", {"type": 'PERIOD', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'tool_settings.use_transform_data_origin')]}), ("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS'}, None), - ("anim.keyframe_delete", {"type": 'I', "value": 'PRESS', "alt": True}, None), + ("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True}, None), ("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), ("collection.create", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), ("collection.objects_remove", {"type": 'G', "value": 'PRESS', "ctrl": True, "alt": True}, None), @@ -5551,6 +5551,7 @@ def km_view3d_walk_modal(_params): ("DECELERATE", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "any": True, "repeat": True}, None), ("ACCELERATE", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "any": True}, None), ("DECELERATE", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "any": True}, None), + ("AXIS_LOCK_Z", {"type": 'Z', "value": 'PRESS'}, None), ]) return keymap diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index b0144672745..714126903d8 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3015,7 +3015,7 @@ def km_pose(params): ("anim.keyframe_insert_by_name", {"type": 'R', "value": 'PRESS', "shift": True}, {"properties": [("type", 'Scaling')]}), - ("anim.keyframe_delete", {"type": 'S', "value": 'PRESS', "alt": True}, None), + ("anim.keyframe_delete_v3d", {"type": 'S', "value": 'PRESS', "alt": True}, None), ("anim.keying_set_active_set", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), *_template_items_context_menu("VIEW3D_MT_pose_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), # Tools @@ -3086,7 +3086,7 @@ def km_object_mode(params): {"properties": [("type", 'Rotation')]}), ("anim.keyframe_insert_by_name", {"type": 'R', "value": 'PRESS', "shift": True}, {"properties": [("type", 'Scaling')]}), - ("anim.keyframe_delete", {"type": 'S', "value": 'PRESS', "alt": True}, None), + ("anim.keyframe_delete_v3d", {"type": 'S', "value": 'PRESS', "alt": True}, None), ("anim.keying_set_active_set", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), *_template_items_context_menu("VIEW3D_MT_object_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ("object.move_to_collection", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), diff --git a/release/scripts/startup/bl_operators/spreadsheet.py b/release/scripts/startup/bl_operators/spreadsheet.py index 1907a69a3d3..b5098d63dac 100644 --- a/release/scripts/startup/bl_operators/spreadsheet.py +++ b/release/scripts/startup/bl_operators/spreadsheet.py @@ -20,6 +20,7 @@ from __future__ import annotations from bpy.types import Operator + class SPREADSHEET_OT_toggle_pin(Operator): '''Turn on or off pinning''' bl_idname = "spreadsheet.toggle_pin" diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 2cc7b828c11..6a3830ad1e4 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -135,7 +135,7 @@ def context_path_decompose(data_path): if base_path: assert(base_path.startswith(".")) - base_path= base_path[1:] + base_path = base_path[1:] if prop_attr: assert(prop_attr.startswith(".")) prop_attr = prop_attr[1:] diff --git a/release/scripts/startup/bl_ui/properties_collection.py b/release/scripts/startup/bl_ui/properties_collection.py index 27de80bb88d..b51d7157c06 100644 --- a/release/scripts/startup/bl_ui/properties_collection.py +++ b/release/scripts/startup/bl_ui/properties_collection.py @@ -35,7 +35,7 @@ def lineart_make_line_type_entry(col, line_type, text_disp, expand, search_from) if line_type.use and expand: col.prop_search(line_type, "layer", search_from, "layers", icon='GREASEPENCIL') - col.prop_search(line_type, "material", search_from, + col.prop_search(line_type, "material", search_from, "materials", icon='SHADING_TEXTURE') @@ -90,7 +90,7 @@ class COLLECTION_PT_lineart_collection(CollectionButtonsPanel, Panel): row = layout.row(align=True, heading="Masks") row.active = collection.lineart_use_intersection_mask - for i in range(0,8): + for i in range(8): row.prop(collection, "lineart_intersection_mask", index=i, text=str(i), toggle=True) diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index e71ea2f31a4..b273eee4e19 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -93,8 +93,8 @@ class GPENCIL_MT_layer_context_menu(Menu): gpd = ob.data gpl = gpd.layers.active - layout.operator("gpencil.layer_duplicate", text="Duplicate", icon='DUPLICATE').mode='ALL' - layout.operator("gpencil.layer_duplicate", text="Duplicate Empty Keyframes").mode='EMPTY' + layout.operator("gpencil.layer_duplicate", text="Duplicate", icon='DUPLICATE').mode = 'ALL' + layout.operator("gpencil.layer_duplicate", text="Duplicate Empty Keyframes").mode = 'EMPTY' layout.separator() @@ -113,8 +113,8 @@ class GPENCIL_MT_layer_context_menu(Menu): layout.operator("gpencil.layer_merge", icon='SORT_ASC', text="Merge Down") layout.separator() - layout.operator("gpencil.layer_duplicate_object", text="Copy Layer to Selected").only_active=True - layout.operator("gpencil.layer_duplicate_object", text="Copy All Layers to Selected").only_active=False + layout.operator("gpencil.layer_duplicate_object", text="Copy Layer to Selected").only_active = True + layout.operator("gpencil.layer_duplicate_object", text="Copy All Layers to Selected").only_active = False class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 0da0716e850..de743033036 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -847,6 +847,7 @@ class GreasePencilLayerRelationsPanel: col.enabled = bool(gpl.viewlayer_render) col.prop(gpl, "use_viewlayer_masks") + class GreasePencilLayerDisplayPanel: def draw(self, context): diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 96920af1c7e..afbc3abf302 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -72,8 +72,9 @@ class CLIP_PT_marker_display(Panel): col.prop(view, "show_marker_pattern", text="Pattern") col.prop(view, "show_marker_search", text="Search") - col.active = view.show_track_path col.prop(view, "show_track_path", text="Path") + col = col.column() + col.active = view.show_track_path col.prop(view, "path_length", text="Length") col = row.column() @@ -113,7 +114,6 @@ class CLIP_PT_clip_display(Panel): row = layout.row() col = row.column() col.prop(sc.clip_user, "use_render_undistorted", text="Render Undistorted") - col.prop(sc, "lock_selection", text="Lock to Selection") col = row.column() col.prop(sc, "show_stable", text="Show Stable") col.prop(sc, "show_grid", text="Grid") @@ -190,7 +190,7 @@ class CLIP_HT_header(Header): row.prop(sc, "pivot_point", text="", icon_only=True) row = layout.row(align=True) icon = 'LOCKED' if sc.lock_selection else 'UNLOCKED' - row.prop(sc, "lock_selection", icon=icon, text="") + row.operator("clip.lock_selection_toggle", icon=icon, text="", depress=sc.lock_selection) row.popover(panel='CLIP_PT_display') elif sc.view == 'GRAPH': @@ -250,7 +250,7 @@ class CLIP_HT_header(Header): row.popover(panel='CLIP_PT_mask_display') row = layout.row(align=True) icon = 'LOCKED' if sc.lock_selection else 'UNLOCKED' - row.prop(sc, "lock_selection", icon=icon, text="") + row.operator("clip.lock_selection_toggle", icon=icon, text="", depress=sc.lock_selection) row.popover(panel='CLIP_PT_display') def draw(self, context): @@ -1477,9 +1477,13 @@ class CLIP_MT_track(Menu): layout.separator() - layout.operator("clip.solve_camera", - text="Solve Camera Motion" if tracking_object.is_camera - else "Solve Object Motion") + layout.operator( + "clip.solve_camera", + text=( + "Solve Camera Motion" if tracking_object.is_camera else + "Solve Object Motion" + ), + ) layout.separator() diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index ffb7b9e5c20..84d1c36c53d 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -609,9 +609,9 @@ class DOPESHEET_MT_context_menu(Menu): layout.operator_menu_enum("action.keyframe_type", "type", text="Keyframe Type") if st.mode != 'GPENCIL': - layout.operator_menu_enum("action.handle_type", "type", text="Handle Type") - layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode") - layout.operator_menu_enum("action.easing_type", "type", text="Easing Mode") + layout.operator_menu_enum("action.handle_type", "type", text="Handle Type") + layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode") + layout.operator_menu_enum("action.easing_type", "type", text="Easing Mode") layout.separator() @@ -625,8 +625,8 @@ class DOPESHEET_MT_context_menu(Menu): layout.operator("action.delete") if st.mode == 'GPENCIL': - layout.operator("gpencil.interpolate_reverse") - layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicate Frames") + layout.operator("gpencil.interpolate_reverse") + layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicate Frames") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 31a4aa5da48..0fceb864ac2 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -260,6 +260,7 @@ class IMAGE_MT_image_flip(Menu): layout.operator("image.flip", text="Horizontally").use_flip_x = True layout.operator("image.flip", text="Vertically").use_flip_y = True + class IMAGE_MT_image_invert(Menu): bl_label = "Invert" diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 1208ca0a64a..fba86676ad4 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -694,6 +694,97 @@ class NODE_UL_interface_sockets(bpy.types.UIList): layout.template_node_socket(color=color) +class NodeTreeInterfacePanel: + def draw_socket_list(self, context, in_out, sockets_propname, active_socket_propname): + layout = self.layout + + snode = context.space_data + tree = snode.edit_tree + sockets = getattr(tree, sockets_propname) + active_socket_index = getattr(tree, active_socket_propname) + active_socket = sockets[active_socket_index] if active_socket_index >= 0 else None + + split = layout.row() + + split.template_list("NODE_UL_interface_sockets", in_out, tree, sockets_propname, tree, active_socket_propname) + + ops_col = split.column() + + add_remove_col = ops_col.column(align=True) + props = add_remove_col.operator("node.tree_socket_add", icon='ADD', text="") + props.in_out = in_out + props = add_remove_col.operator("node.tree_socket_remove", icon='REMOVE', text="") + props.in_out = in_out + + ops_col.separator() + + up_down_col = ops_col.column(align=True) + props = up_down_col.operator("node.tree_socket_move", icon='TRIA_UP', text="") + props.in_out = in_out + props.direction = 'UP' + props = up_down_col.operator("node.tree_socket_move", icon='TRIA_DOWN', text="") + props.in_out = in_out + props.direction = 'DOWN' + + if active_socket is not None: + # Mimicking property split. + layout.use_property_split = False + layout.use_property_decorate = False + layout_row = layout.row(align=True) + layout_split = layout_row.split(factor=0.4, align=True) + + label_column = layout_split.column(align=True) + label_column.alignment = 'RIGHT' + # Menu to change the socket type. + label_column.label(text="Type") + + property_row = layout_split.row(align=True) + props = property_row.operator_menu_enum( + "node.tree_socket_change_type", + "socket_type", + text=active_socket.bl_label if active_socket.bl_label else active_socket.bl_idname + ) + props.in_out = in_out + + layout.use_property_split = True + layout.use_property_decorate = False + + layout.prop(active_socket, "name") + # Display descriptions only for Geometry Nodes, since it's only used in the modifier panel. + if tree.type == 'GEOMETRY': + layout.prop(active_socket, "description") + active_socket.draw(context, layout) + + +class NODE_PT_node_tree_interface_inputs(NodeTreeInterfacePanel, Panel): + bl_space_type = 'NODE_EDITOR' + bl_region_type = 'UI' + bl_category = "Group" + bl_label = "Inputs" + + @classmethod + def poll(cls, context): + snode = context.space_data + return snode.edit_tree is not None + + def draw(self, context): + self.draw_socket_list(context, "IN", "inputs", "active_input") + +class NODE_PT_node_tree_interface_outputs(NodeTreeInterfacePanel, Panel): + bl_space_type = 'NODE_EDITOR' + bl_region_type = 'UI' + bl_category = "Group" + bl_label = "Outputs" + + @classmethod + def poll(cls, context): + snode = context.space_data + return snode.edit_tree is not None + + def draw(self, context): + self.draw_socket_list(context, "OUT", "outputs", "active_output") + + # Grease Pencil properties class NODE_PT_annotation(AnnotationDataPanel, Panel): bl_space_type = 'NODE_EDITOR' @@ -752,6 +843,8 @@ classes = ( NODE_PT_quality, NODE_PT_annotation, NODE_UL_interface_sockets, + NODE_PT_node_tree_interface_inputs, + NODE_PT_node_tree_interface_outputs, node_panel(EEVEE_MATERIAL_PT_settings), node_panel(MATERIAL_PT_viewport), diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 7a694108e14..ba91b6e8d50 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -442,7 +442,6 @@ class OUTLINER_PT_filter(Panel): row.prop(space, "use_filter_lib_override_system", text="System Overrides") - classes = ( OUTLINER_HT_header, OUTLINER_MT_editor_menus, diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 99384ac713d..55714e0b0a5 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -400,7 +400,7 @@ class SEQUENCER_MT_view(Menu): layout.menu("SEQUENCER_MT_proxy") layout.operator_context = 'INVOKE_DEFAULT' - + layout.separator() layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("sequencer.refresh_all", icon='FILE_REFRESH', text="Refresh All") @@ -467,6 +467,7 @@ class SEQUENCER_MT_select_handle(Menu): layout.operator("sequencer.select_handles", text="Left Neighbor").side = 'LEFT_NEIGHBOR' layout.operator("sequencer.select_handles", text="Right Neighbor").side = 'RIGHT_NEIGHBOR' + class SEQUENCER_MT_select_channel(Menu): bl_label = "Select Channel" @@ -1415,7 +1416,7 @@ class SEQUENCER_PT_source(SequencerButtonsPanel, Panel): split.label(text="%dx%d" % size, translate=False) else: split.label(text="None") - #FPS + # FPS if elem.orig_fps: split = col.split(factor=0.5, align=False) split.alignment = 'RIGHT' @@ -1424,7 +1425,6 @@ class SEQUENCER_PT_source(SequencerButtonsPanel, Panel): split.label(text="%.2f" % elem.orig_fps, translate=False) - class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel): bl_label = "Scene" bl_category = "Strip" @@ -1857,7 +1857,7 @@ class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel): @classmethod def poll(cls, context): show_developer_ui = context.preferences.view.show_developer_ui - return cls.has_sequencer(context) and context.scene.sequence_editor and show_developer_ui + return cls.has_sequencer(context) and context.scene.sequence_editor and show_developer_ui def draw(self, context): layout = self.layout @@ -2286,12 +2286,15 @@ class SEQUENCER_PT_snapping(Panel): layout.use_property_decorate = False col = layout.column(heading="Snap to", align=True) - col.prop(sequencer_tool_settings, "snap_to_current_frame" ) + col.prop(sequencer_tool_settings, "snap_to_current_frame") col.prop(sequencer_tool_settings, "snap_to_hold_offset") col = layout.column(heading="Ignore", align=True) col.prop(sequencer_tool_settings, "snap_ignore_muted", text="Muted Strips") - col.prop(sequencer_tool_settings, "snap_ignore_sound",text="Sound Strips") + col.prop(sequencer_tool_settings, "snap_ignore_sound", text="Sound Strips") + + col = layout.column() + col.prop(sequencer_tool_settings, "use_snap_current_frame_to_strips") classes = ( diff --git a/release/scripts/startup/bl_ui/space_spreadsheet.py b/release/scripts/startup/bl_ui/space_spreadsheet.py index ad696f23db4..afdbfea5091 100644 --- a/release/scripts/startup/bl_ui/space_spreadsheet.py +++ b/release/scripts/startup/bl_ui/space_spreadsheet.py @@ -58,7 +58,7 @@ class SPREADSHEET_HT_header(bpy.types.Header): layout.label(text="No active viewer node.", icon='INFO') layout.separator_spacer() - + row = layout.row(align=True) sub = row.row(align=True) sub.active = self.selection_filter_available(space) @@ -115,6 +115,7 @@ class SPREADSHEET_HT_header(bpy.types.Header): return False return True + classes = ( SPREADSHEET_HT_header, ) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index f9359a8b4a0..7e6fde1ebaf 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1391,7 +1391,6 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel): row.separator() row.label(text="Path") - for i, library in enumerate(paths.asset_libraries): name_col.prop(library, "name", text="") row = path_col.row() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 80cede9ee5a..df41445ee6f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2765,23 +2765,27 @@ class VIEW3D_MT_make_single_user(Menu): props = layout.operator("object.make_single_user", text="Object") props.object = True - props.obdata = props.material = props.animation = False + props.obdata = props.material = props.animation = props.obdata_animation = False props = layout.operator("object.make_single_user", text="Object & Data") props.object = props.obdata = True - props.material = props.animation = False + props.material = props.animation = props.obdata_animation = False props = layout.operator("object.make_single_user", text="Object & Data & Materials") props.object = props.obdata = props.material = True - props.animation = False + props.animation = props.obdata_animation = False props = layout.operator("object.make_single_user", text="Materials") props.material = True - props.object = props.obdata = props.animation = False + props.object = props.obdata = props.animation = props.obdata_animation = False props = layout.operator("object.make_single_user", text="Object Animation") props.animation = True - props.object = props.obdata = props.material = False + props.object = props.obdata = props.material = props.obdata_animation = False + + props = layout.operator("object.make_single_user", text="Object Data Animation") + props.obdata_animation = props.obdata = True + props.object = props.material = props.animation = False class VIEW3D_MT_object_convert(Menu): @@ -3129,7 +3133,6 @@ class VIEW3D_MT_mask(Menu): layout.menu("VIEW3D_MT_random_mask", text="Random Mask") - class VIEW3D_MT_face_sets(Menu): bl_label = "Face Sets" @@ -3259,6 +3262,7 @@ class VIEW3D_MT_random_mask(Menu): op = layout.operator("sculpt.mask_init", text='Per Loose Part') op.mode = 'RANDOM_PER_LOOSE_PART' + class VIEW3D_MT_particle(Menu): bl_label = "Particle" diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index bc385faf378..46fed79332d 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1731,7 +1731,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff from bl_ui.space_toolsystem_common import ToolSelectPanelHelper tool = ToolSelectPanelHelper.tool_active_from_context(context) - if tool and tool.idname != 'builtin_brush.Tint': + if tool and tool.idname != 'builtin_brush.Tint': return False gptool = brush.gpencil_tool @@ -2057,7 +2057,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel): from bl_ui.space_toolsystem_common import ToolSelectPanelHelper tool = ToolSelectPanelHelper.tool_active_from_context(context) - if tool and tool.idname in('builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'): + if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}: return False if brush.gpencil_tool == 'TINT': @@ -2118,7 +2118,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel): from bl_ui.space_toolsystem_common import ToolSelectPanelHelper tool = ToolSelectPanelHelper.tool_active_from_context(context) - if tool and tool.idname in('builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'): + if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}: return False if brush.gpencil_tool == 'TINT': diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index 2fc2d966ea9..ceffeaaff6c 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -383,6 +383,7 @@ class BUILTIN_KSI_Available(KeyingSetInfo): ############################### + class WholeCharacterMixin: # these prefixes should be avoided, as they are not really bones # that animators should be touching (or need to touch) diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index b25d2be7de0..d617cfab988 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -506,6 +506,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeCurveResample"), NodeItem("GeometryNodeMeshToCurve"), NodeItem("GeometryNodeCurveToPoints"), + NodeItem("GeometryNodeCurveEndpoints"), NodeItem("GeometryNodeCurveLength"), NodeItem("GeometryNodeCurveReverse"), ]), @@ -515,6 +516,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeCurveStar"), NodeItem("GeometryNodeCurveSpiral"), NodeItem("GeometryNodeCurveQuadraticBezier"), + NodeItem("GeometryNodeCurvePrimitiveQuadrilateral"), NodeItem("GeometryNodeCurvePrimitiveBezierSegment"), ]), GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=[ @@ -546,7 +548,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeTriangulate"), NodeItem("GeometryNodeEdgeSplit"), NodeItem("GeometryNodeSubdivisionSurface"), - NodeItem("GeometryNodeSubdivide"), + NodeItem("GeometryNodeMeshSubdivide"), ]), GeometryNodeCategory("GEO_PRIMITIVES_MESH", "Mesh Primitives", items=[ NodeItem("GeometryNodeMeshCircle"), @@ -558,6 +560,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeMeshLine"), NodeItem("GeometryNodeMeshUVSphere"), ]), + GeometryNodeCategory("GEO_POINT", "Point", items=[ NodeItem("GeometryNodePointDistribute"), NodeItem("GeometryNodePointInstance"), diff --git a/release/scripts/templates_py/image_processing.py b/release/scripts/templates_py/image_processing.py index 2392faf440c..ab14436ad8e 100644 --- a/release/scripts/templates_py/image_processing.py +++ b/release/scripts/templates_py/image_processing.py @@ -20,9 +20,9 @@ input_image.pixels.foreach_get(pixel_data.ravel()) # Do whatever image processing you want using numpy here: # Example 1: Inverse red green and blue channels. -pixel_data[:,:,:3] = 1.0 - pixel_data[:,:,:3] +pixel_data[:, :, :3] = 1.0 - pixel_data[:, :, :3] # Example 2: Change gamma on the red channel. -pixel_data[:,:,0] = np.power(pixel_data[:,:,0], 1.5) +pixel_data[:, :, 0] = np.power(pixel_data[:, :, 0], 1.5) # Create output image. if output_image_name in bpy.data.images: diff --git a/release/scripts/templates_py/operator_mesh_add.py b/release/scripts/templates_py/operator_mesh_add.py index aa5b9ebf880..3fc7636459b 100644 --- a/release/scripts/templates_py/operator_mesh_add.py +++ b/release/scripts/templates_py/operator_mesh_add.py @@ -6,6 +6,7 @@ from bpy.props import ( FloatProperty, ) + def add_box(width, height, depth): """ This function takes inputs and returns vertex and face arrays. diff --git a/source/blender/blenkernel/BKE_anim_data.h b/source/blender/blenkernel/BKE_anim_data.h index 6c07708b5ef..14ab9f21424 100644 --- a/source/blender/blenkernel/BKE_anim_data.h +++ b/source/blender/blenkernel/BKE_anim_data.h @@ -50,8 +50,8 @@ bool id_can_have_animdata(const struct ID *id); /* Get AnimData from the given ID-block */ struct AnimData *BKE_animdata_from_id(struct ID *id); -/* Add AnimData to the given ID-block */ -struct AnimData *BKE_animdata_add_id(struct ID *id); +/* Ensure AnimData is present in the ID-block (when supported). */ +struct AnimData *BKE_animdata_ensure_id(struct ID *id); /* Set active action used by AnimData from the given ID-block */ bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct bAction *act); diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 6a1f1feb14f..5fda30224c6 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -39,8 +39,8 @@ struct ReportList; /* Attribute.domain */ /** - * \warning: Careful when changing existing items. Arrays may be initialized from this (e.g. - * #DATASET_layout_hierarchy). + * \warning Careful when changing existing items. + * Arrays may be initialized from this (e.g. #DATASET_layout_hierarchy). */ typedef enum AttributeDomain { ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */ diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 9d286b94b04..dffd70c077f 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 8 +#define BLENDER_FILE_SUBVERSION 11 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index f47cdf32ca0..0326386e5c1 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -76,6 +76,7 @@ struct Collection *BKE_collection_duplicate(struct Main *bmain, /* Master Collection for Scene */ +#define BKE_SCENE_COLLECTION_NAME "Scene Collection" struct Collection *BKE_collection_master_add(void); /* Collection Objects */ diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h index 9112877b5a3..ce7df62389f 100644 --- a/source/blender/blenkernel/BKE_editmesh.h +++ b/source/blender/blenkernel/BKE_editmesh.h @@ -24,7 +24,7 @@ * only concerned with low level operations on the #BMEditMesh structure. */ -#include "BKE_customdata.h" +#include "DNA_customdata_types.h" #include "bmesh.h" #ifdef __cplusplus @@ -44,34 +44,39 @@ struct Scene; /** * This structure is used for mesh edit-mode. * - * through this, you get access to both the edit #BMesh, - * its tessellation, and various stuff that doesn't belong in the BMesh - * struct itself. + * Through this, you get access to both the edit #BMesh, its tessellation, + * and various data that doesn't belong in the #BMesh struct itself + * (mostly related to mesh evaluation). * - * the entire derivedmesh and modifier system works with this structure, - * and not BMesh. Mesh->edit_bmesh stores a pointer to this structure. */ + * The entire modifier system works with this structure, and not #BMesh. + * #Mesh.edit_bmesh stores a pointer to this structure. */ typedef struct BMEditMesh { struct BMesh *bm; - /* we store tessellations as triplets of three loops, - * which each define a triangle. */ + /** + * Face triangulation (tessellation) is stored as triplets of three loops, + * which each define a triangle. + * + * \see #MLoopTri as the documentation gives useful hints that apply to this data too. + */ struct BMLoop *(*looptris)[3]; int tottri; struct Mesh *mesh_eval_final, *mesh_eval_cage; - /** Cached cage bounding box for selection. */ + /** Cached cage bounding box of `mesh_eval_cage` for selection. */ struct BoundBox *bb_cage; /** Evaluated mesh data-mask. */ CustomData_MeshMasks lastDataMask; - /* Selection mode. */ + /** Selection mode (#SCE_SELECT_VERTEX, #SCE_SELECT_EDGE & #SCE_SELECT_FACE). */ short selectmode; + /** The active material (assigned to newly created faces). */ short mat_nr; - /* Temp variables for x-mirror editing. */ - int mirror_cdlayer; /* -1 is invalid */ + /** Temp variables for x-mirror editing (-1 when the layer does not exist). */ + int mirror_cdlayer; /** * ID data is older than edit-mode data. @@ -94,11 +99,11 @@ void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em, void BKE_editmesh_looptri_and_normals_calc(BMEditMesh *em); -BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate); +BMEditMesh *BKE_editmesh_create(BMesh *bm); BMEditMesh *BKE_editmesh_copy(BMEditMesh *em); BMEditMesh *BKE_editmesh_from_object(struct Object *ob); -void BKE_editmesh_free_derivedmesh(BMEditMesh *em); -void BKE_editmesh_free(BMEditMesh *em); +void BKE_editmesh_free_derived_caches(BMEditMesh *em); +void BKE_editmesh_free_data(BMEditMesh *em); float (*BKE_editmesh_vert_coords_alloc(struct Depsgraph *depsgraph, struct BMEditMesh *em, diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 657e66729e1..c11c34cb312 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -282,20 +282,25 @@ bool BKE_gpencil_from_image(struct SpaceImage *sima, const float size, const bool mask); -/* Iterator */ +/* Iterators */ /* frame & stroke are NULL if it is a layer callback. */ typedef void (*gpIterCb)(struct bGPDlayer *layer, struct bGPDframe *frame, struct bGPDstroke *stroke, void *thunk); -void BKE_gpencil_visible_stroke_iter(struct ViewLayer *view_layer, - struct Object *ob, +void BKE_gpencil_visible_stroke_iter(struct bGPdata *gpd, gpIterCb layer_cb, gpIterCb stroke_cb, - void *thunk, - bool do_onion, - int cfra); + void *thunk); + +void BKE_gpencil_visible_stroke_advanced_iter(struct ViewLayer *view_layer, + struct Object *ob, + gpIterCb layer_cb, + gpIterCb stroke_cb, + void *thunk, + bool do_onion, + int cfra); extern void (*BKE_gpencil_batch_cache_dirty_tag_cb)(struct bGPdata *gpd); extern void (*BKE_gpencil_batch_cache_free_cb)(struct bGPdata *gpd); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 8d76a025e87..12560ebed7b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -299,7 +299,7 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop, struct MLoopTri *mlooptri, const float (*poly_normals)[3]); -/* *** mesh_normals.c *** */ +/* *** mesh_normals.cc *** */ void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me); void BKE_mesh_calc_normals_mapping(struct MVert *mverts, @@ -494,7 +494,7 @@ void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh, void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loopnors)[3]); void BKE_mesh_set_custom_normals_from_vertices(struct Mesh *mesh, float (*r_custom_vertnors)[3]); -/* *** mesh_evaluate.c *** */ +/* *** mesh_evaluate.cc *** */ void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly, const struct MLoop *loopstart, diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index aed8c44a031..b223d3872ff 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -27,6 +27,7 @@ typedef enum eMeshBatchDirtyMode { BKE_MESH_BATCH_DIRTY_SELECT, BKE_MESH_BATCH_DIRTY_SELECT_PAINT, BKE_MESH_BATCH_DIRTY_SHADING, + BKE_MESH_BATCH_DIRTY_DEFORM, BKE_MESH_BATCH_DIRTY_UVEDIT_ALL, BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT, } eMeshBatchDirtyMode; diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7f4189a3a4a..b1a38ec5700 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -141,7 +141,10 @@ typedef void *SocketGetCPPValueFunction; * Defines the appearance and behavior of a socket in the UI. */ typedef struct bNodeSocketType { - char idname[64]; /* identifier name */ + /* Identifier name */ + char idname[64]; + /* Type label */ + char label[64]; void (*draw)(struct bContext *C, struct uiLayout *layout, @@ -412,7 +415,7 @@ typedef struct bNodeTreeType { void (*node_add_init)(struct bNodeTree *ntree, struct bNode *bnode); /* Check if the socket type is valid for this tree type. */ - bool (*valid_socket_type)(enum eNodeSocketDatatype socket_type, struct bNodeTreeType *ntreetype); + bool (*valid_socket_type)(struct bNodeTreeType *ntreetype, struct bNodeSocketType *socket_type); /* RNA integration */ ExtensionRNA rna_ext; @@ -554,8 +557,12 @@ void nodeRegisterSocketType(struct bNodeSocketType *stype); void nodeUnregisterSocketType(struct bNodeSocketType *stype); bool nodeSocketIsRegistered(struct bNodeSocket *sock); struct GHashIterator *nodeSocketTypeGetIterator(void); +const char *nodeSocketTypeLabel(const bNodeSocketType *stype); + +bool nodeIsStaticSocketType(const struct bNodeSocketType *stype); const char *nodeStaticSocketType(int type, int subtype); const char *nodeStaticSocketInterfaceType(int type, int subtype); +const char *nodeStaticSocketLabel(int type, int subtype); /* helper macros for iterating over node types */ #define NODE_SOCKET_TYPES_BEGIN(stype) \ @@ -605,7 +612,11 @@ struct bNodeSocket *nodeInsertStaticSocket(struct bNodeTree *ntree, const char *name); void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); -void nodeModifySocketType( +void nodeModifySocketType(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocket *sock, + const char *idname); +void nodeModifySocketTypeStatic( struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, int type, int subtype); struct bNode *nodeAddNode(const struct bContext *C, struct bNodeTree *ntree, const char *idname); @@ -1406,7 +1417,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_VOLUME_TO_MESH 1026 #define GEO_NODE_ATTRIBUTE_COMBINE_XYZ 1027 #define GEO_NODE_ATTRIBUTE_SEPARATE_XYZ 1028 -#define GEO_NODE_SUBDIVIDE 1029 +#define GEO_NODE_MESH_SUBDIVIDE 1029 #define GEO_NODE_ATTRIBUTE_REMOVE 1030 #define GEO_NODE_ATTRIBUTE_CONVERT 1031 #define GEO_NODE_MESH_PRIMITIVE_CUBE 1032 @@ -1446,6 +1457,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_CURVE_PRIMITIVE_CIRCLE 1066 #define GEO_NODE_VIEWER 1067 #define GEO_NODE_CURVE_PRIMITIVE_LINE 1068 +#define GEO_NODE_CURVE_ENDPOINTS 1069 +#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070 /** \} */ diff --git a/source/blender/blenkernel/BKE_node_ui_storage.hh b/source/blender/blenkernel/BKE_node_ui_storage.hh deleted file mode 100644 index 4ec165aad8c..00000000000 --- a/source/blender/blenkernel/BKE_node_ui_storage.hh +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#pragma once - -#include <mutex> - -#include "BLI_hash.hh" -#include "BLI_map.hh" -#include "BLI_session_uuid.h" -#include "BLI_set.hh" - -#include "DNA_ID.h" -#include "DNA_customdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_session_uuid_types.h" - -#include "BKE_attribute.h" - -struct ModifierData; -struct Object; -struct bNode; -struct bNodeTree; -struct bContext; - -/** - * Contains the context necessary to determine when to display settings for a certain node tree - * that may be used for multiple modifiers and objects. The object name and modifier session UUID - * are used instead of pointers because they are re-allocated between evaluations. - * - * \note This does not yet handle the context of nested node trees. - */ -class NodeTreeEvaluationContext { - private: - std::string object_name_; - SessionUUID modifier_session_uuid_; - - public: - NodeTreeEvaluationContext(const Object &object, const ModifierData &modifier) - { - object_name_ = reinterpret_cast<const ID &>(object).name; - modifier_session_uuid_ = modifier.session_uuid; - } - - uint64_t hash() const - { - return blender::get_default_hash_2(object_name_, modifier_session_uuid_); - } - - friend bool operator==(const NodeTreeEvaluationContext &a, const NodeTreeEvaluationContext &b) - { - return a.object_name_ == b.object_name_ && - BLI_session_uuid_is_equal(&a.modifier_session_uuid_, &b.modifier_session_uuid_); - } -}; - -enum class NodeWarningType { - Error, - Warning, - Info, -}; - -struct NodeWarning { - NodeWarningType type; - std::string message; -}; - -struct AvailableAttributeInfo { - std::string name; - AttributeDomain domain; - CustomDataType data_type; - - uint64_t hash() const - { - return blender::get_default_hash(name); - } - - friend bool operator==(const AvailableAttributeInfo &a, const AvailableAttributeInfo &b) - { - return a.name == b.name; - } -}; - -struct NodeUIStorage { - blender::Vector<NodeWarning> warnings; - blender::Set<AvailableAttributeInfo> attribute_hints; -}; - -struct NodeTreeUIStorage { - std::mutex mutex; - blender::Map<NodeTreeEvaluationContext, blender::Map<std::string, NodeUIStorage>> context_map; - - /** - * Attribute search uses this to store the fake info for the string typed into a node, in order - * to pass the info to the execute callback that sets node socket values. This is mutable since - * we can count on only one attribute search being open at a time, and there is no real data - * stored here. - */ - mutable AvailableAttributeInfo dummy_info_for_search; -}; - -const NodeUIStorage *BKE_node_tree_ui_storage_get_from_context(const bContext *C, - const bNodeTree &ntree, - const bNode &node); - -void BKE_nodetree_ui_storage_free_for_context(bNodeTree &ntree, - const NodeTreeEvaluationContext &context); - -void BKE_nodetree_error_message_add(bNodeTree &ntree, - const NodeTreeEvaluationContext &context, - const bNode &node, - const NodeWarningType type, - std::string message); - -void BKE_nodetree_attribute_hint_add(bNodeTree &ntree, - const NodeTreeEvaluationContext &context, - const bNode &node, - const blender::StringRef attribute_name, - const AttributeDomain domain, - const CustomDataType data_type); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index cd66f026828..a16822fd7dd 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -70,10 +70,6 @@ void BKE_object_free_curve_cache(struct Object *ob); void BKE_object_free_derived_caches(struct Object *ob); void BKE_object_free_caches(struct Object *object); -void BKE_object_preview_geometry_set_add(struct Object *ob, - const uint64_t key, - struct GeometrySet *geometry_set); - void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd); void BKE_object_modifier_gpencil_hook_reset(struct Object *ob, struct HookGpencilModifierData *hmd); @@ -378,6 +374,10 @@ void BKE_object_runtime_free_data(struct Object *object); void BKE_object_batch_cache_dirty_tag(struct Object *ob); void BKE_object_data_batch_cache_dirty_tag(struct ID *object_data); +void BKE_object_data_eval_batch_cache_dirty_tag(struct Depsgraph *depsgraph, + struct ID *object_data); +void BKE_object_data_eval_batch_cache_deform_tag(struct Depsgraph *depsgraph, + struct ID *object_data); /* this function returns a superset of the scenes selection based on relationships */ diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 8731162b720..3f99a0dc793 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -45,7 +45,7 @@ extern "C" { #define PTCACHE_RESET_OUTDATED 2 /* #define PTCACHE_RESET_FREE 3 */ /*UNUSED*/ -/* Add the blendfile name after blendcache_ */ +/* Add the blend-file name after `blendcache_`. */ #define PTCACHE_EXT ".bphys" #define PTCACHE_PATH "blendcache_" diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 9792f819bf9..6d58e165ea3 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -124,14 +124,16 @@ bool BKE_scene_camera_switch_update(struct Scene *scene); const char *BKE_scene_find_marker_name(const struct Scene *scene, int frame); const char *BKE_scene_find_last_marker_name(const struct Scene *scene, int frame); -int BKE_scene_frame_snap_by_seconds(struct Scene *scene, double interval_in_seconds, int cfra); +int BKE_scene_frame_snap_by_seconds(struct Scene *scene, double interval_in_seconds, int frame); /* checks for cycle, returns 1 if it's all OK */ bool BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce); +float BKE_scene_ctime_get(const struct Scene *scene); +float BKE_scene_frame_to_ctime(const struct Scene *scene, const int frame); + float BKE_scene_frame_get(const struct Scene *scene); -float BKE_scene_frame_to_ctime(const struct Scene *scene, const float frame); -void BKE_scene_frame_set(struct Scene *scene, double cfra); +void BKE_scene_frame_set(struct Scene *scene, float frame); struct TransformOrientationSlot *BKE_scene_orientation_slot_get_from_flag(struct Scene *scene, int flag); diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index 70b8743bcd2..59b1c2b28d9 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -145,7 +145,7 @@ typedef struct StudioLight { void BKE_studiolight_init(void); void BKE_studiolight_free(void); -void BKE_studiolight_default(SolidLight lights[4], float light_ambient[4]); +void BKE_studiolight_default(SolidLight lights[4], float light_ambient[3]); struct StudioLight *BKE_studiolight_find(const char *name, int flag); struct StudioLight *BKE_studiolight_findindex(int index, int flag); struct StudioLight *BKE_studiolight_find_default(int flag); diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h index efac5d9097f..2973a432723 100644 --- a/source/blender/blenkernel/BKE_undo_system.h +++ b/source/blender/blenkernel/BKE_undo_system.h @@ -162,6 +162,13 @@ typedef enum UndoTypeFlags { * \note Callback is still supposed to properly deal with a NULL context pointer. */ UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE = 1 << 0, + + /** + * When the active undo step is of this type, it must be read before loading other undo steps. + * + * This is typically used for undo systems that store both before/after states. + */ + UNDOTYPE_FLAG_DECODE_ACTIVE_STEP = 1 << 1, } UndoTypeFlags; /* Expose since we need to perform operations on specific undo types (rarely). */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 7a057d8fc1b..2c25b940578 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -184,13 +184,13 @@ set(SRC intern/mesh.c intern/mesh_boolean_convert.cc intern/mesh_convert.c - intern/mesh_evaluate.c + intern/mesh_evaluate.cc intern/mesh_fair.cc intern/mesh_iterators.c intern/mesh_mapping.c intern/mesh_merge.c intern/mesh_mirror.c - intern/mesh_normals.c + intern/mesh_normals.cc intern/mesh_remap.c intern/mesh_remesh_voxel.c intern/mesh_runtime.c @@ -215,7 +215,6 @@ set(SRC intern/multires_versioning.c intern/nla.c intern/node.cc - intern/node_ui_storage.cc intern/object.c intern/object_deform.c intern/object_dupli.cc @@ -331,7 +330,6 @@ set(SRC BKE_customdata_file.h BKE_data_transfer.h BKE_deform.h - BKE_spline.hh BKE_displist.h BKE_displist_tangent.h BKE_duplilist.h @@ -399,7 +397,6 @@ set(SRC BKE_multires.h BKE_nla.h BKE_node.h - BKE_node_ui_storage.hh BKE_object.h BKE_object_deform.h BKE_object_facemap.h @@ -423,6 +420,7 @@ set(SRC BKE_softbody.h BKE_sound.h BKE_speaker.h + BKE_spline.hh BKE_studiolight.h BKE_subdiv.h BKE_subdiv_ccg.h @@ -767,6 +765,7 @@ add_dependencies(bf_blenkernel bf_dna) if(WITH_GTESTS) set(TEST_SRC + intern/action_test.cc intern/armature_test.cc intern/cryptomatte_test.cc intern/fcurve_test.cc diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 933cddfdf1b..ba8cf8debe9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1976,7 +1976,7 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph, BKE_sculpt_update_object_before_eval(obedit); } - BKE_editmesh_free_derivedmesh(em); + BKE_editmesh_free_derived_caches(em); Mesh *me_cage; Mesh *me_final; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 13ca5ecf23c..d55f023d209 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -497,9 +497,8 @@ void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve) } /* Reconstruct group channel pointers. - * Assumes that the channels are still in the proper order, i.e. that channels of the same group - * are adjacent in the act->channels list. It also assumes that the groups - * referred to by the FCurves are already in act->groups. + * Assumes that the groups referred to by the FCurves are already in act->groups. + * Reorders the main channel list to match group order. */ void BKE_action_groups_reconstruct(bAction *act) { @@ -514,23 +513,30 @@ void BKE_action_groups_reconstruct(bAction *act) BLI_listbase_clear(&group->channels); } - bActionGroup *grp; - bActionGroup *last_grp = NULL; - LISTBASE_FOREACH (FCurve *, fcurve, &act->curves) { - if (fcurve->grp == NULL) { - continue; - } + /* Sort the channels into the group lists, destroying the act->curves list. */ + ListBase ungrouped = {NULL, NULL}; - grp = fcurve->grp; - if (last_grp != grp) { - /* If this is the first time we see this group, this must be the first channel. */ - grp->channels.first = fcurve; + LISTBASE_FOREACH_MUTABLE (FCurve *, fcurve, &act->curves) { + if (fcurve->grp) { + BLI_assert(BLI_findindex(&act->groups, fcurve->grp) >= 0); + + BLI_addtail(&fcurve->grp->channels, fcurve); + } + else { + BLI_addtail(&ungrouped, fcurve); } + } + + /* Recombine into the main list. */ + BLI_listbase_clear(&act->curves); - /* This is the last channel, until it's overwritten by a later iteration. */ - grp->channels.last = fcurve; - last_grp = grp; + LISTBASE_FOREACH (bActionGroup *, group, &act->groups) { + /* Copy the list header to preserve the pointers in the group. */ + ListBase tmp = group->channels; + BLI_movelisttolist(&act->curves, &tmp); } + + BLI_movelisttolist(&act->curves, &ungrouped); } /* Remove the given channel from all groups */ diff --git a/source/blender/blenkernel/intern/action_test.cc b/source/blender/blenkernel/intern/action_test.cc new file mode 100644 index 00000000000..c02eca966ad --- /dev/null +++ b/source/blender/blenkernel/intern/action_test.cc @@ -0,0 +1,144 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 Blender Foundation + * All rights reserved. + */ + +#include "BKE_action.h" + +#include "DNA_action_types.h" +#include "DNA_anim_types.h" + +#include "BLI_listbase.h" + +#include "testing/testing.h" + +namespace blender::bke::tests { + +TEST(action_groups, ReconstructGroupsWithReordering) +{ + /* Construct an Action with three groups. */ + bAction action = {{nullptr}}; + FCurve groupAcurve1 = {nullptr}; + FCurve groupAcurve2 = {nullptr}; + FCurve groupBcurve1 = {nullptr}; + FCurve groupBcurve2 = {nullptr}; + FCurve groupBcurve3 = {nullptr}; + /* Group C has no curves intentionally. */ + FCurve groupDcurve1 = {nullptr}; + FCurve groupDcurve2 = {nullptr}; + + groupAcurve1.rna_path = (char *)"groupAcurve1"; + groupAcurve2.rna_path = (char *)"groupAcurve2"; + groupBcurve1.rna_path = (char *)"groupBcurve1"; + groupBcurve2.rna_path = (char *)"groupBcurve2"; + groupDcurve1.rna_path = (char *)"groupDcurve1"; + groupBcurve3.rna_path = (char *)"groupBcurve3"; + groupDcurve2.rna_path = (char *)"groupDcurve2"; + + BLI_addtail(&action.curves, &groupAcurve1); + BLI_addtail(&action.curves, &groupAcurve2); + BLI_addtail(&action.curves, &groupBcurve1); + BLI_addtail(&action.curves, &groupBcurve2); + BLI_addtail(&action.curves, &groupDcurve1); + BLI_addtail(&action.curves, &groupBcurve3); /* <-- The error that should be corrected. */ + BLI_addtail(&action.curves, &groupDcurve2); + + /* Introduce another error type, by changing some `prev` pointers. */ + groupBcurve1.prev = nullptr; + groupBcurve3.prev = &groupBcurve2; + groupDcurve1.prev = &groupBcurve3; + + bActionGroup groupA = {nullptr}; + bActionGroup groupB = {nullptr}; + bActionGroup groupC = {nullptr}; + bActionGroup groupD = {nullptr}; + strcpy(groupA.name, "groupA"); + strcpy(groupB.name, "groupB"); + strcpy(groupC.name, "groupC"); + strcpy(groupD.name, "groupD"); + + BLI_addtail(&action.groups, &groupA); + BLI_addtail(&action.groups, &groupB); + BLI_addtail(&action.groups, &groupC); + BLI_addtail(&action.groups, &groupD); + + groupAcurve1.grp = &groupA; + groupAcurve2.grp = &groupA; + groupBcurve1.grp = &groupB; + groupBcurve2.grp = &groupB; + groupBcurve3.grp = &groupB; + groupDcurve1.grp = &groupD; + groupDcurve2.grp = &groupD; + + groupA.channels.first = &groupAcurve1; + groupA.channels.last = &groupAcurve2; + groupB.channels.first = &groupBcurve1; + groupB.channels.last = &groupBcurve3; /* The last channel in group B, after group C curve 1. */ + groupD.channels.first = &groupDcurve1; + groupD.channels.last = &groupDcurve2; + + EXPECT_EQ(groupA.channels.first, &groupAcurve1); + EXPECT_EQ(groupA.channels.last, &groupAcurve2); + EXPECT_EQ(groupB.channels.first, &groupBcurve1); + EXPECT_EQ(groupB.channels.last, &groupBcurve3); + EXPECT_EQ(groupC.channels.first, nullptr); + EXPECT_EQ(groupC.channels.last, nullptr); + EXPECT_EQ(groupD.channels.first, &groupDcurve1); + EXPECT_EQ(groupD.channels.last, &groupDcurve2); + + BKE_action_groups_reconstruct(&action); + + EXPECT_EQ(action.curves.first, &groupAcurve1); + EXPECT_EQ(action.curves.last, &groupDcurve2); + + EXPECT_EQ(groupA.prev, nullptr); + EXPECT_EQ(groupB.prev, &groupA); + EXPECT_EQ(groupC.prev, &groupB); + EXPECT_EQ(groupD.prev, &groupC); + + EXPECT_EQ(groupA.next, &groupB); + EXPECT_EQ(groupB.next, &groupC); + EXPECT_EQ(groupC.next, &groupD); + EXPECT_EQ(groupD.next, nullptr); + + EXPECT_EQ(groupA.channels.first, &groupAcurve1); + EXPECT_EQ(groupA.channels.last, &groupAcurve2); + EXPECT_EQ(groupB.channels.first, &groupBcurve1); + EXPECT_EQ(groupB.channels.last, &groupBcurve3); + EXPECT_EQ(groupC.channels.first, nullptr); + EXPECT_EQ(groupC.channels.last, nullptr); + EXPECT_EQ(groupD.channels.first, &groupDcurve1); + EXPECT_EQ(groupD.channels.last, &groupDcurve2); + + EXPECT_EQ(groupAcurve1.prev, nullptr); + EXPECT_EQ(groupAcurve2.prev, &groupAcurve1); + EXPECT_EQ(groupBcurve1.prev, &groupAcurve2); + EXPECT_EQ(groupBcurve2.prev, &groupBcurve1); + EXPECT_EQ(groupBcurve3.prev, &groupBcurve2); + EXPECT_EQ(groupDcurve1.prev, &groupBcurve3); + EXPECT_EQ(groupDcurve2.prev, &groupDcurve1); + + EXPECT_EQ(groupAcurve1.next, &groupAcurve2); + EXPECT_EQ(groupAcurve2.next, &groupBcurve1); + EXPECT_EQ(groupBcurve1.next, &groupBcurve2); + EXPECT_EQ(groupBcurve2.next, &groupBcurve3); + EXPECT_EQ(groupBcurve3.next, &groupDcurve1); + EXPECT_EQ(groupDcurve1.next, &groupDcurve2); + EXPECT_EQ(groupDcurve2.next, nullptr); +} + +} // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c index 7e5313f0e4a..7e4ab754500 100644 --- a/source/blender/blenkernel/intern/anim_data.c +++ b/source/blender/blenkernel/intern/anim_data.c @@ -89,16 +89,16 @@ bool id_can_have_animdata(const ID *id) return id_type_can_have_animdata(GS(id->name)); } -/* Get AnimData from the given ID-block. In order for this to work, we assume that - * the AnimData pointer is stored immediately after the given ID-block in the struct, - * as per IdAdtTemplate. +/** + * Get #AnimData from the given ID-block. */ AnimData *BKE_animdata_from_id(ID *id) { - /* only some ID-blocks have this info for now, so we cast the - * types that do to be of type IdAdtTemplate, and extract the - * AnimData that way - */ + /* In order for this to work, we assume that the #AnimData pointer is stored + * immediately after the given ID-block in the struct, as per IdAdtTemplate. */ + + /* Only some ID-blocks have this info for now, so we cast the types that do + * to be of type IdAdtTemplate, and add the AnimData to it using the template. */ if (id_can_have_animdata(id)) { IdAdtTemplate *iat = (IdAdtTemplate *)id; return iat->adt; @@ -106,16 +106,16 @@ AnimData *BKE_animdata_from_id(ID *id) return NULL; } -/* Add AnimData to the given ID-block. In order for this to work, we assume that - * the AnimData pointer is stored immediately after the given ID-block in the struct, - * as per IdAdtTemplate. Also note that +/** + * Ensure #AnimData exists in the given ID-block (when supported). */ -AnimData *BKE_animdata_add_id(ID *id) +AnimData *BKE_animdata_ensure_id(ID *id) { - /* Only some ID-blocks have this info for now, so we cast the - * types that do to be of type IdAdtTemplate, and add the AnimData - * to it using the template - */ + /* In order for this to work, we assume that the #AnimData pointer is stored + * immediately after the given ID-block in the struct, as per IdAdtTemplate. */ + + /* Only some ID-blocks have this info for now, so we cast the types that do + * to be of type IdAdtTemplate, and add the AnimData to it using the template. */ if (id_can_have_animdata(id)) { IdAdtTemplate *iat = (IdAdtTemplate *)id; @@ -444,7 +444,7 @@ void BKE_animdata_merge_copy( return; } - // TODO: we must unset all "tweakmode" flags + /* TODO: we must unset all "tweak-mode" flags. */ if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) { CLOG_ERROR( &LOG, @@ -667,7 +667,7 @@ void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa /* get animdata from src, and create for destination (if needed) */ srcAdt = BKE_animdata_from_id(srcID); - dstAdt = BKE_animdata_add_id(dstID); + dstAdt = BKE_animdata_ensure_id(dstID); if (ELEM(NULL, srcAdt, dstAdt)) { if (G.debug & G_DEBUG) { @@ -1590,10 +1590,10 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, AnimData *adt) /* relink active track/strip - even though strictly speaking this should only be used * if we're in 'tweaking mode', we need to be able to have this loaded back for - * undo, but also since users may not exit tweakmode before saving (T24535) + * undo, but also since users may not exit tweak-mode before saving (T24535). */ /* TODO: it's not really nice that anyone should be able to save the file in this - * state, but it's going to be too hard to enforce this single case... */ + * state, but it's going to be too hard to enforce this single case. */ BLO_read_data_address(reader, &adt->act_track); BLO_read_data_address(reader, &adt->actstrip); } diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index 579f671e2b0..ebff6015df1 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -191,8 +191,7 @@ bool BKE_appdir_folder_documents(char *dir) { dir[0] = '\0'; - const char *documents_path = (const char *)GHOST_getUserSpecialDir( - GHOST_kUserSpecialDirDocuments); + const char *documents_path = GHOST_getUserSpecialDir(GHOST_kUserSpecialDirDocuments); /* Usual case: Ghost gave us the documents path. We're done here. */ if (documents_path && BLI_is_dir(documents_path)) { @@ -462,7 +461,7 @@ static bool get_path_user_ex(char *targetpath, } user_path[0] = '\0'; - user_base_path = (const char *)GHOST_getUserDir(version, blender_version_decimal(version)); + user_base_path = GHOST_getUserDir(version, blender_version_decimal(version)); if (user_base_path) { BLI_strncpy(user_path, user_base_path, FILE_MAX); } @@ -522,7 +521,7 @@ static bool get_path_system_ex(char *targetpath, } system_path[0] = '\0'; - system_base_path = (const char *)GHOST_getSystemDir(version, blender_version_decimal(version)); + system_base_path = GHOST_getSystemDir(version, blender_version_decimal(version)); if (system_base_path) { BLI_strncpy(system_path, system_base_path, FILE_MAX); } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 22d6cfba893..b8ed519e8d1 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2843,7 +2843,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) * hopefully this is OK. */ BKE_pose_ensure(NULL, ob, arm, true); - ctime = BKE_scene_frame_get(scene); /* not accurate... */ + ctime = BKE_scene_ctime_get(scene); /* not accurate... */ /* In edit-mode or rest-position we read the data from the bones. */ if (arm->edbo || (arm->flag & ARM_RESTPOS)) { diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 2552b5eefea..5e9259f05bb 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -47,6 +47,7 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_lattice.h" diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 0f8956a1a91..35ae2d2dbef 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -562,7 +562,7 @@ static void splineik_evaluate_bone( * spline dictates, while still maintaining roll control from the existing bone animation. */ mul_m3_m3m3(pose_mat, dmat, rmat); - /* Attempt to reduce shearing, though I doubt this'll really help too much now... */ + /* Attempt to reduce shearing, though I doubt this will really help too much now. */ normalize_m3(pose_mat); mul_m3_m3m3(base_pose_mat, dmat, base_pose_mat); @@ -828,7 +828,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob { DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); BLI_assert(object->type == OB_ARMATURE); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ bArmature *armature = (bArmature *)object->data; if (armature->flag & ARM_RESTPOS) { return; @@ -869,7 +869,7 @@ void BKE_pose_eval_bone(struct Depsgraph *depsgraph, Scene *scene, Object *objec else { if ((pchan->flag & POSE_DONE) == 0) { /* TODO(sergey): Use time source node for time. */ - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ BKE_pose_where_is_bone(depsgraph, scene, object, pchan, ctime, 1); } } @@ -897,7 +897,7 @@ void BKE_pose_constraints_evaluate(struct Depsgraph *depsgraph, } else { if ((pchan->flag & POSE_DONE) == 0) { - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ BKE_pose_where_is_bone(depsgraph, scene, object, pchan, ctime, 1); } } @@ -981,7 +981,7 @@ void BKE_pose_iktree_evaluate(struct Depsgraph *depsgraph, DEG_debug_print_eval_subdata( depsgraph, __func__, object->id.name, object, "rootchan", rootchan->name, rootchan); BLI_assert(object->type == OB_ARMATURE); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ if (armature->flag & ARM_RESTPOS) { return; } @@ -1002,7 +1002,7 @@ void BKE_pose_splineik_evaluate(struct Depsgraph *depsgraph, DEG_debug_print_eval_subdata( depsgraph, __func__, object->id.name, object, "rootchan", rootchan->name, rootchan); BLI_assert(object->type == OB_ARMATURE); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ if (armature->flag & ARM_RESTPOS) { return; } @@ -1031,7 +1031,7 @@ void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph, Scene *scene, Object *ob bPose *pose = object->pose; BLI_assert(pose != NULL); UNUSED_VARS_NDEBUG(pose); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); BLI_assert(object->type == OB_ARMATURE); /* Release the IK tree. */ diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index f31d8f5ade7..912cc66920e 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -128,7 +128,7 @@ static void setup_app_userdef(BlendFileData *bfd) } /** - * Context matching, handle no-ui case + * Context matching, handle no-UI case. * * \note this is called on Undo so any slow conversion functions here * should be avoided or check (mode != LOAD_UNDO). diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 0284b20d98e..164f921c7ac 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -1290,9 +1290,9 @@ BVHTree *bvhtree_from_editmesh_looptri( } /** - * Builds a bvh tree where nodes are the looptri faces of the given dm + * Builds a BVH-tree where nodes are the looptri faces of the given mesh. * - * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces_ex + * \note for edit-mesh this is currently a duplicate of #bvhtree_from_mesh_faces_ex */ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, const struct MVert *vert, diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 30e9ae39b67..eaba5d33a20 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -314,7 +314,7 @@ bool BKE_cachefile_filepath_get(const Main *bmain, if (cache_file->is_sequence && BLI_path_frame_get(r_filepath, &fframe, &frame_len)) { Scene *scene = DEG_get_evaluated_scene(depsgraph); - const float ctime = BKE_scene_frame_get(scene); + const float ctime = BKE_scene_ctime_get(scene); const float fps = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base); const float frame = BKE_cachefile_time_offset(cache_file, ctime, fps); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 2bca3f5da76..8678a659c0a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -597,7 +597,7 @@ static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexC Cloth *cloth = clmd->clothObject; if (clmd->clothObject) { - /* inverse matrix is not uptodate... */ + /* Inverse matrix is not up to date. */ invert_m4_m4(ob->imat, ob->obmat); for (i = 0; i < cloth->mvert_num; i++) { diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 39698bde622..cf32bc15962 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -888,7 +888,7 @@ Collection *BKE_collection_master_add() { /* Not an actual datablock, but owned by scene. */ Collection *master_collection = BKE_libblock_alloc( - NULL, ID_GR, "Master Collection", LIB_ID_CREATE_NO_MAIN); + NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN); master_collection->id.flag |= LIB_EMBEDDED_DATA; master_collection->flag |= COLLECTION_IS_MASTER; master_collection->color_tag = COLLECTION_COLOR_NONE; diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 4e1ec9ba35e..26894495777 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -398,8 +398,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, if (crazyspace_modifier_supports_deform_matrices(md)) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (defmats == NULL) { - /* NOTE: Evaluated object si re-set to its original undeformed - * state. */ + /* NOTE: Evaluated object is re-set to its original un-deformed state. */ Mesh *me = object_eval.data; me_eval = BKE_mesh_copy_for_eval(me, true); crazyspace_init_verts_and_matrices(me_eval, &defmats, &deformedVerts); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 8dac20f6fe9..52996e3bcc7 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -248,7 +248,7 @@ typedef struct PaintAdjData { int *n_target; /** Index to start reading n_target for each point. */ int *n_index; - /** Num of neighs for each point. */ + /** Number of neighbors for each point. */ int *n_num; /** Vertex adjacency flags. */ int *flags; @@ -3818,7 +3818,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, ob, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false); numOfVerts_p = mesh_p->totvert; @@ -3834,7 +3834,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, ob, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); mesh_c = dynamicPaint_brush_mesh_get(brush); numOfVerts_c = mesh_c->totvert; @@ -3894,7 +3894,7 @@ static void dynamicPaint_brushObjectCalculateVelocity( ob, false, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); copy_m4_m4(prev_obmat, ob->obmat); @@ -3906,7 +3906,7 @@ static void dynamicPaint_brushObjectCalculateVelocity( ob, false, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); /* calculate speed */ @@ -6271,7 +6271,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, brushObj, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); } @@ -6312,7 +6312,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, brushObj, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); } diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 2eb6b488da2..9cae74e4e9a 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -39,15 +39,14 @@ #include "BKE_mesh_wrapper.h" #include "BKE_object.h" -BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate) +/** + * \note The caller is responsible for ensuring triangulation data, + * typically by calling #BKE_editmesh_looptri_calc. + */ +BMEditMesh *BKE_editmesh_create(BMesh *bm) { BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__); - em->bm = bm; - if (do_tessellate) { - BKE_editmesh_looptri_calc(em); - } - return em; } @@ -209,7 +208,7 @@ void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em, }); } -void BKE_editmesh_free_derivedmesh(BMEditMesh *em) +void BKE_editmesh_free_derived_caches(BMEditMesh *em) { if (em->mesh_eval_cage) { BKE_id_free(NULL, em->mesh_eval_cage); @@ -223,9 +222,9 @@ void BKE_editmesh_free_derivedmesh(BMEditMesh *em) } /* Does not free the #BMEditMesh struct itself. */ -void BKE_editmesh_free(BMEditMesh *em) +void BKE_editmesh_free_data(BMEditMesh *em) { - BKE_editmesh_free_derivedmesh(em); + BKE_editmesh_free_derived_caches(em); if (em->looptris) { MEM_freeN(em->looptris); diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c index e5e639fa3f1..da4ea742656 100644 --- a/source/blender/blenkernel/intern/editmesh_tangent.c +++ b/source/blender/blenkernel/intern/editmesh_tangent.c @@ -25,6 +25,7 @@ #include "DNA_defs.h" #include "DNA_meshdata_types.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_editmesh_tangent.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 947417af55d..2b48683a3a8 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1283,10 +1283,10 @@ static void compute_obstaclesemission(Scene *scene, # endif /* Update frame time, this is considering current subframe fraction * BLI_mutex_lock() called in manta_step(), so safe to update subframe here - * TODO(sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph) + * TODO(sebbas): Using BKE_scene_ctime_get(scene) instead of new DEG_get_ctime(depsgraph) * as subframes don't work with the latter yet. */ BKE_object_modifier_update_subframe( - depsgraph, scene, effecobj, true, 5, BKE_scene_frame_get(scene), eModifierType_Fluid); + depsgraph, scene, effecobj, true, 5, BKE_scene_ctime_get(scene), eModifierType_Fluid); if (subframes) { obstacles_from_mesh(effecobj, fds, fes, &bb_temp, subframe_dt); @@ -1616,7 +1616,7 @@ static void emit_from_particles(Object *flow_ob, } /* `DEG_get_ctime(depsgraph)` does not give sub-frame time. */ - state.time = BKE_scene_frame_get(scene); + state.time = BKE_scene_ctime_get(scene); if (psys_get_particle_state(&sim, p, &state, 0) == 0) { continue; @@ -2820,10 +2820,10 @@ static void compute_flowsemission(Scene *scene, # endif /* Update frame time, this is considering current subframe fraction * BLI_mutex_lock() called in manta_step(), so safe to update subframe here - * TODO(sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph) + * TODO(sebbas): Using BKE_scene_ctime_get(scene) instead of new DEG_get_ctime(depsgraph) * as subframes don't work with the latter yet. */ BKE_object_modifier_update_subframe( - depsgraph, scene, flowobj, true, 5, BKE_scene_frame_get(scene), eModifierType_Fluid); + depsgraph, scene, flowobj, true, 5, BKE_scene_ctime_get(scene), eModifierType_Fluid); /* Emission from particles. */ if (ffs->source == FLUID_FLOW_SOURCE_PARTICLES) { diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 1a880b0c427..529096b8523 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -2703,19 +2703,57 @@ static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer } /* -------------------------------------------------------------------- */ -/** \name Iterators +/** \name Iterator * - * Iterate over all visible stroke of all visible layers inside a gpObject. - * Also take into account onion-skinning. + * Iterate over all visible stroke of all visible layers inside a grease pencil datablock. * \{ */ -void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer, - Object *ob, +void BKE_gpencil_visible_stroke_iter(bGPdata *gpd, gpIterCb layer_cb, gpIterCb stroke_cb, - void *thunk, - bool do_onion, - int cfra) + void *thunk) +{ + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + + if (gpl->flag & GP_LAYER_HIDE) { + continue; + } + + /* If scale to 0 the layer must be invisible. */ + if (is_zero_v3(gpl->scale)) { + continue; + } + + bGPDframe *act_gpf = gpl->actframe; + if (layer_cb) { + layer_cb(gpl, act_gpf, NULL, thunk); + } + + if (act_gpf) { + LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) { + if (gps->totpoints == 0) { + continue; + } + stroke_cb(gpl, act_gpf, gps, thunk); + } + } + } +} + +/* -------------------------------------------------------------------- */ +/** \name Advanced Iterator + * + * Iterate over all visible stroke of all visible layers inside a gpObject. + * Also take into account onion-skinning. + * \{ */ + +void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer, + Object *ob, + gpIterCb layer_cb, + gpIterCb stroke_cb, + void *thunk, + bool do_onion, + int cfra) { bGPdata *gpd = (bGPdata *)ob->data; const bool is_multiedit = ((GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) && (!GPENCIL_PLAY_ON(gpd))); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index a1f82b1dcb6..8a70f065e40 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2087,7 +2087,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* check if object has any animation data */ if (ob->nlastrips.first) { /* Add AnimData block */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); /* IPO first to take into any non-NLA'd Object Animation */ if (ob->ipo) { @@ -2109,7 +2109,7 @@ void do_versions_ipos_to_animato(Main *bmain) } else if ((ob->ipo) || (ob->action)) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Action first - so that Action name get conserved */ if (ob->action) { @@ -2133,7 +2133,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* check PoseChannels for constraints with local data */ if (ob->pose) { /* Verify if there's AnimData block */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { @@ -2159,7 +2159,7 @@ void do_versions_ipos_to_animato(Main *bmain) */ if (con->ipo) { /* Verify if there's AnimData block, just in case */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); /* although this was the constraint's local IPO, we still need to provide con * so that drivers can be added properly... @@ -2176,7 +2176,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* check constraint channels - we need to remove them anyway... */ if (ob->constraintChannels.first) { /* Verify if there's AnimData block */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); for (conchan = ob->constraintChannels.first; conchan; conchan = conchann) { /* get pointer to next Constraint Channel */ @@ -2217,7 +2217,7 @@ void do_versions_ipos_to_animato(Main *bmain) */ if (key->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Shapekey data... */ ipo_to_animdata(bmain, id, key->ipo, NULL, NULL, NULL); @@ -2242,7 +2242,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (ma->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Material data... */ ipo_to_animdata(bmain, id, ma->ipo, NULL, NULL, NULL); @@ -2267,7 +2267,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (wo->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert World data... */ ipo_to_animdata(bmain, id, wo->ipo, NULL, NULL, NULL); @@ -2288,7 +2288,7 @@ void do_versions_ipos_to_animato(Main *bmain) if (ed && ed->seqbasep) { Sequence *seq; - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); SEQ_ALL_BEGIN (ed, seq) { IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; @@ -2346,7 +2346,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (te->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Texture data... */ ipo_to_animdata(bmain, id, te->ipo, NULL, NULL, NULL); @@ -2371,7 +2371,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (ca->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Camera data... */ ipo_to_animdata(bmain, id, ca->ipo, NULL, NULL, NULL); @@ -2396,7 +2396,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (la->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Light data... */ ipo_to_animdata(bmain, id, la->ipo, NULL, NULL, NULL); @@ -2421,7 +2421,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (cu->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Curve data... */ ipo_to_animdata(bmain, id, cu->ipo, NULL, NULL, NULL); diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c index 1856a08e198..f9437eeaffa 100644 --- a/source/blender/blenkernel/intern/lattice_deform.c +++ b/source/blender/blenkernel/intern/lattice_deform.c @@ -108,7 +108,7 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob invert_m4_m4(imat, latmat); } - /* Prefetch latice deform group weights. */ + /* Prefetch lattice deform group weights. */ int defgrp_index = -1; const MDeformVert *dvert = BKE_lattice_deform_verts_get(oblatt); if (lt->vgroup[0] && dvert) { diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c index 10ab0a06dd0..48179e0c3bf 100644 --- a/source/blender/blenkernel/intern/layer_utils.c +++ b/source/blender/blenkernel/intern/layer_utils.c @@ -23,6 +23,7 @@ #include "BLI_array.h" #include "BKE_collection.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_layer.h" diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index c00fba852ef..9d0349a7e89 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -1642,9 +1642,8 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_ * already. */ if (!is_orig_name_used) { - /* Don't bother updating prev_ static variables here, this case is not supposed to happen - * that often, and is not straight-forward here, so just ignore and reset them to default. - */ + /* Don't bother updating `prev_*` static variables here, this case is not supposed to happen + * that often, and is not straight-forward here, so just ignore and reset them to default. */ prev_id_type = ID_LINK_PLACEHOLDER; prev_final_base_name[0] = '\0'; prev_number = MIN_NUMBER - 1; @@ -1684,7 +1683,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_ continue; } - /* Update prev_ static variables, in case next call is for the same type of IDs and with the + /* Update `prev_*` static variables, in case next call is for the same type of IDs and with the * same initial base name, we can skip a lot of above process. */ prev_id_type = id_type; strcpy(prev_final_base_name, base_name); diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 9bfb01a257c..798d9562150 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -38,6 +38,7 @@ #include "BLI_mesh_boolean.hh" #include "BLI_mesh_intersect.hh" #include "BLI_span.hh" +#include "BLI_task.hh" namespace blender::meshintersect { @@ -309,22 +310,38 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, clean_obmat(*obmats[mi]); r_info->to_target_transform[mi] = inv_target_mat * objn_mat; - /* Skip the matrix multiplication for each point when there is no transform for a mesh, - * for example when the first mesh is already in the target space. (Note the logic directly - * above, which uses an identity matrix with a null input transform). */ + Vector<Vert *> verts(me->totvert); + Span<MVert> mverts = Span(me->mvert, me->totvert); + + /* Allocate verts + * Skip the matrix multiplication for each point when there is no transform for a mesh, + * for example when the first mesh is already in the target space. (Note the logic + * directly above, which uses an identity matrix with a null input transform). */ if (obmats[mi] == nullptr) { - for (const MVert &vert : Span(me->mvert, me->totvert)) { - const float3 co = float3(vert.co); - r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co.x, co.y, co.z), v); - ++v; - } + threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) { + float3 co; + for (int i : range) { + co = float3(mverts[i].co); + mpq3 mco = mpq3(co.x, co.y, co.z); + double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); + verts[i] = new Vert(mco, dco, NO_INDEX, i); + } + }); } else { - for (const MVert &vert : Span(me->mvert, me->totvert)) { - const float3 co = r_info->to_target_transform[mi] * float3(vert.co); - r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co.x, co.y, co.z), v); - ++v; - } + threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) { + float3 co; + for (int i : range) { + co = r_info->to_target_transform[mi] * float3(mverts[i].co); + mpq3 mco = mpq3(co.x, co.y, co.z); + double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); + verts[i] = new Vert(mco, dco, NO_INDEX, i); + } + }); + } + for (int i : mverts.index_range()) { + r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]); + ++v; } for (const MPoly &poly : Span(me->mpoly, me->totpoly)) { diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.cc index 7290679bc07..91fd022a316 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -23,7 +23,7 @@ * Functions to evaluate mesh data. */ -#include <limits.h> +#include <climits> #include "MEM_guardedalloc.h" @@ -200,7 +200,7 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const } const MLoop *l_iter = loopstart; - float(*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); + float(*vertexcos)[3] = (float(*)[3])BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); /* pack vertex cos into an array for area_poly_v3 */ for (int i = 0; i < mpoly->totloop; i++, l_iter++) { @@ -236,7 +236,7 @@ float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array) int i, l_iter = mpoly->loopstart; float area; - float(*vertexcos)[2] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); + float(*vertexcos)[2] = (float(*)[2])BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); /* pack vertex cos into an array for area_poly_v2 */ for (i = 0; i < mpoly->totloop; i++, l_iter++) { @@ -404,7 +404,7 @@ void BKE_mesh_poly_edgehash_insert(EdgeHash *ehash, const MPoly *mp, const MLoop ml = &ml_next[i - 1]; /* last loop */ while (i-- != 0) { - BLI_edgehash_reinsert(ehash, ml->v, ml_next->v, NULL); + BLI_edgehash_reinsert(ehash, ml->v, ml_next->v, nullptr); ml = ml_next; ml_next++; @@ -676,7 +676,7 @@ void BKE_mesh_calc_volume(const MVert *mverts, /** \} */ /* -------------------------------------------------------------------- */ -/** \name NGon Tessellation (NGon/Tessface Conversion) +/** \name NGon Tessellation (NGon to MFace Conversion) * \{ */ static void bm_corners_to_loops_ex(ID *id, @@ -692,9 +692,9 @@ static void bm_corners_to_loops_ex(ID *id, MFace *mf = mface + findex; for (int i = 0; i < numTex; i++) { - MTFace *texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); + MTFace *texface = (MTFace *)CustomData_get_n(fdata, CD_MTFACE, findex, i); - MLoopUV *mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); + MLoopUV *mloopuv = (MLoopUV *)CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); copy_v2_v2(mloopuv->uv, texface->uv[0]); mloopuv++; copy_v2_v2(mloopuv->uv, texface->uv[1]); @@ -709,8 +709,8 @@ static void bm_corners_to_loops_ex(ID *id, } for (int i = 0; i < numCol; i++) { - MLoopCol *mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); - MCol *mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); + MCol *mcol = (MCol *)CustomData_get_n(fdata, CD_MCOL, findex, i); MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]); mloopcol++; @@ -725,8 +725,8 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_TESSLOOPNORMAL)) { - float(*lnors)[3] = CustomData_get(ldata, loopstart, CD_NORMAL); - short(*tlnors)[3] = CustomData_get(fdata, findex, CD_TESSLOOPNORMAL); + float(*lnors)[3] = (float(*)[3])CustomData_get(ldata, loopstart, CD_NORMAL); + short(*tlnors)[3] = (short(*)[3])CustomData_get(fdata, findex, CD_TESSLOOPNORMAL); const int max = mf->v4 ? 4 : 3; for (int i = 0; i < max; i++, lnors++, tlnors++) { @@ -735,8 +735,8 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_MDISPS)) { - MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); - MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); + MDisps *ld = (MDisps *)CustomData_get(ldata, loopstart, CD_MDISPS); + MDisps *fd = (MDisps *)CustomData_get(fdata, findex, CD_MDISPS); float(*disps)[3] = fd->disps; int tot = mf->v4 ? 4 : 3; int corners; @@ -750,9 +750,9 @@ static void bm_corners_to_loops_ex(ID *id, corners = multires_mdisp_corners(fd); if (corners == 0) { - /* Empty MDisp layers appear in at least one of the sintel.blend files. + /* Empty #MDisp layers appear in at least one of the `sintel.blend` files. * Not sure why this happens, but it seems fine to just ignore them here. - * If (corners == 0) for a non-empty layer though, something went wrong. */ + * If `corners == 0` for a non-empty layer though, something went wrong. */ BLI_assert(fd->totdisp == 0); } else { @@ -767,7 +767,8 @@ static void bm_corners_to_loops_ex(ID *id, MEM_freeN(ld->disps); } - ld->disps = MEM_malloc_arrayN((size_t)side_sq, sizeof(float[3]), "converted loop mdisps"); + ld->disps = (float(*)[3])MEM_malloc_arrayN( + (size_t)side_sq, sizeof(float[3]), "converted loop mdisps"); if (fd->disps) { memcpy(ld->disps, disps, (size_t)side_sq * sizeof(float[3])); } @@ -801,15 +802,16 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh) /** * The same as #BKE_mesh_convert_mfaces_to_mpolys - * but oriented to be used in #do_versions from readfile.c - * the difference is how active/render/clone/stencil indices are handled here + * but oriented to be used in #do_versions from `readfile.c` + * the difference is how active/render/clone/stencil indices are handled here. * - * normally thay're being set from pdata which totally makes sense for meshes which are already - * converted to bmesh structures, but when loading older files indices shall be updated in other - * way around, so newly added pdata and ldata would have this indices set based on fdata layer + * normally they're being set from `pdata` which totally makes sense for meshes which are already + * converted to #BMesh structures, but when loading older files indices shall be updated in other + * way around, so newly added `pdata` and `ldata` would have this indices set + * based on `fdata` layer. * * this is normally only needed when reading older files, - * in all other cases #BKE_mesh_convert_mfaces_to_mpolys shall be always used + * in all other cases #BKE_mesh_convert_mfaces_to_mpolys shall be always used. */ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh) { @@ -864,7 +866,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData_free(pdata, totpoly_i); totpoly = totface_i; - mpoly = MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted"); + mpoly = (MPoly *)MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted"); CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, totpoly); numTex = CustomData_number_of_layers(fdata, CD_MTFACE); @@ -876,7 +878,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, totloop += mf->v4 ? 4 : 3; } - mloop = MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted"); + mloop = (MLoop *)MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted"); CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop); @@ -900,7 +902,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, me->flag &= ~ME_FGON; } - polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX); + polyindex = (int *)CustomData_get_layer(fdata, CD_ORIGINDEX); j = 0; /* current loop index */ ml = mloop; @@ -946,7 +948,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, /* NOTE: we don't convert NGons at all, these are not even real ngons, * they have their own UV's, colors etc - its more an editing feature. */ - BLI_edgehash_free(eh, NULL); + BLI_edgehash_free(eh, nullptr); *r_totpoly = totpoly; *r_totloop = totloop; @@ -1050,8 +1052,8 @@ void BKE_mesh_polygon_flip_ex(MPoly *mpoly, void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata) { - MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS); - BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, NULL, mdisp, true); + MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); + BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true); } /** @@ -1061,12 +1063,12 @@ void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata) */ void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly) { - MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS); + MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); MPoly *mp; int i; for (mp = mpoly, i = 0; i < totpoly; mp++, i++) { - BKE_mesh_polygon_flip_ex(mp, mloop, ldata, NULL, mdisp, true); + BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nullptr, mdisp, true); } } @@ -1277,7 +1279,7 @@ void BKE_mesh_calc_relative_deform(const MPoly *mpoly, const MPoly *mp; int i; - int *vert_accum = MEM_calloc_arrayN((size_t)totvert, sizeof(*vert_accum), __func__); + int *vert_accum = (int *)MEM_calloc_arrayN((size_t)totvert, sizeof(*vert_accum), __func__); memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * (size_t)totvert); diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 9a3333fce6c..ca6c60557a6 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -998,7 +998,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, } /* TODO: I'm not sure edge seam flag is enough to define UV islands? - * Maybe we should also consider UVmaps values + * Maybe we should also consider UV-maps values * themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?). * Would make things much more complex though, * and each UVMap would then need its own mesh mapping, not sure we want that at all! diff --git a/source/blender/blenkernel/intern/mesh_normals.c b/source/blender/blenkernel/intern/mesh_normals.cc index 89fd7f92d94..2fe132fc684 100644 --- a/source/blender/blenkernel/intern/mesh_normals.c +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -25,7 +25,7 @@ * \see bmesh_mesh_normals.c for the equivalent #BMesh functionality. */ -#include <limits.h> +#include <climits> #include "CLG_log.h" @@ -90,15 +90,15 @@ void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh) mesh->mpoly, mesh->totloop, mesh->totpoly, - NULL, + nullptr, mesh->mface, mesh->totface, - NULL, - NULL, + nullptr, + nullptr, only_face_normals); } -/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL +/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-nullptr * and vertex normals are stored in actual mverts. */ void BKE_mesh_calc_normals_mapping(MVert *mverts, @@ -150,13 +150,13 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, } /* if we are not calculating verts and no verts were passes then we have nothing to do */ - if ((only_face_normals == true) && (r_polyNors == NULL) && (r_faceNors == NULL)) { + if ((only_face_normals == true) && (r_polyNors == nullptr) && (r_faceNors == nullptr)) { CLOG_WARN(&LOG, "called with nothing to do"); return; } if (!pnors) { - pnors = MEM_calloc_arrayN((size_t)numPolys, sizeof(float[3]), __func__); + pnors = (float(*)[3])MEM_calloc_arrayN((size_t)numPolys, sizeof(float[3]), __func__); } /* NO NEED TO ALLOC YET */ /* if (!fnors) fnors = MEM_calloc_arrayN(numFaces, sizeof(float[3]), "face nors mesh.c"); */ @@ -165,7 +165,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, /* vertex normals are optional, they require some extra calculations, * so make them optional */ BKE_mesh_calc_normals_poly( - mverts, NULL, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false); + mverts, nullptr, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false); } else { /* only calc poly normals */ @@ -177,7 +177,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, if (origIndexFace && /* fnors == r_faceNors */ /* NO NEED TO ALLOC YET */ - fnors != NULL && + fnors != nullptr && numFaces) { const MFace *mf = mfaces; for (int i = 0; i < numFaces; i++, mf++, origIndexFace++) { @@ -196,23 +196,23 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, } /* if (fnors != r_faceNors) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */ - fnors = pnors = NULL; + fnors = pnors = nullptr; } -typedef struct MeshCalcNormalsData { +struct MeshCalcNormalsData { const MPoly *mpolys; const MLoop *mloop; MVert *mverts; float (*pnors)[3]; float (*lnors_weighted)[3]; float (*vnors)[3]; -} MeshCalcNormalsData; +}; static void mesh_calc_normals_poly_cb(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls)) { - MeshCalcNormalsData *data = userdata; + MeshCalcNormalsData *data = (MeshCalcNormalsData *)userdata; const MPoly *mp = &data->mpolys[pidx]; BKE_mesh_calc_poly_normal(mp, data->mloop + mp->loopstart, data->mverts, data->pnors[pidx]); @@ -222,7 +222,7 @@ static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls)) { - MeshCalcNormalsData *data = userdata; + MeshCalcNormalsData *data = (MeshCalcNormalsData *)userdata; const MPoly *mp = &data->mpolys[pidx]; const MLoop *ml = &data->mloop[mp->loopstart]; const MVert *mverts = data->mverts; @@ -232,7 +232,7 @@ static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata, float(*lnors_weighted)[3] = data->lnors_weighted; const int nverts = mp->totloop; - float(*edgevecbuf)[3] = BLI_array_alloca(edgevecbuf, (size_t)nverts); + float(*edgevecbuf)[3] = (float(*)[3])BLI_array_alloca(edgevecbuf, (size_t)nverts); /* Polygon Normal and edge-vector */ /* inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors */ @@ -285,7 +285,7 @@ static void mesh_calc_normals_poly_finalize_cb(void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict UNUSED(tls)) { - MeshCalcNormalsData *data = userdata; + MeshCalcNormalsData *data = (MeshCalcNormalsData *)userdata; MVert *mv = &data->mverts[vidx]; float *no = data->vnors[vidx]; @@ -315,42 +315,40 @@ void BKE_mesh_calc_normals_poly(MVert *mverts, settings.min_iter_per_thread = 1024; if (only_face_normals) { - BLI_assert((pnors != NULL) || (numPolys == 0)); - BLI_assert(r_vertnors == NULL); - - MeshCalcNormalsData data = { - .mpolys = mpolys, - .mloop = mloop, - .mverts = mverts, - .pnors = pnors, - }; + BLI_assert((pnors != nullptr) || (numPolys == 0)); + BLI_assert(r_vertnors == nullptr); + + MeshCalcNormalsData data; + data.mpolys = mpolys; + data.mloop = mloop; + data.mverts = mverts; + data.pnors = pnors; BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_cb, &settings); return; } float(*vnors)[3] = r_vertnors; - float(*lnors_weighted)[3] = MEM_malloc_arrayN( + float(*lnors_weighted)[3] = (float(*)[3])MEM_malloc_arrayN( (size_t)numLoops, sizeof(*lnors_weighted), __func__); bool free_vnors = false; /* first go through and calculate normals for all the polys */ - if (vnors == NULL) { - vnors = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vnors), __func__); + if (vnors == nullptr) { + vnors = (float(*)[3])MEM_calloc_arrayN((size_t)numVerts, sizeof(*vnors), __func__); free_vnors = true; } else { memset(vnors, 0, sizeof(*vnors) * (size_t)numVerts); } - MeshCalcNormalsData data = { - .mpolys = mpolys, - .mloop = mloop, - .mverts = mverts, - .pnors = pnors, - .lnors_weighted = lnors_weighted, - .vnors = vnors, - }; + MeshCalcNormalsData data; + data.mpolys = mpolys; + data.mloop = mloop; + data.mverts = mverts; + data.pnors = pnors; + data.lnors_weighted = lnors_weighted; + data.vnors = vnors; /* Compute poly normals, and prepare weighted loop normals. */ BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, &settings); @@ -400,19 +398,21 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh) } } - float(*poly_nors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + float(*poly_nors)[3] = (float(*)[3])CustomData_get_layer(&mesh->pdata, CD_NORMAL); const bool do_vert_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) != 0; - const bool do_poly_normals = (mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL || poly_nors == NULL); + const bool do_poly_normals = (mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL || + poly_nors == nullptr); if (do_vert_normals || do_poly_normals) { - const bool do_add_poly_nors_cddata = (poly_nors == NULL); + const bool do_add_poly_nors_cddata = (poly_nors == nullptr); if (do_add_poly_nors_cddata) { - poly_nors = MEM_malloc_arrayN((size_t)mesh->totpoly, sizeof(*poly_nors), __func__); + poly_nors = (float(*)[3])MEM_malloc_arrayN( + (size_t)mesh->totpoly, sizeof(*poly_nors), __func__); } /* calculate poly/vert normals */ BKE_mesh_calc_normals_poly(mesh->mvert, - NULL, + nullptr, mesh->totvert, mesh->mloop, mesh->mpoly, @@ -438,13 +438,13 @@ void BKE_mesh_calc_normals(Mesh *mesh) TIMEIT_START_AVERAGED(BKE_mesh_calc_normals); #endif BKE_mesh_calc_normals_poly(mesh->mvert, - NULL, + nullptr, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, - NULL, + nullptr, false); #ifdef DEBUG_TIME TIMEIT_END_AVERAGED(BKE_mesh_calc_normals); @@ -459,10 +459,10 @@ void BKE_mesh_calc_normals_looptri(MVert *mverts, int looptri_num, float (*r_tri_nors)[3]) { - float(*tnorms)[3] = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms"); - float(*fnors)[3] = (r_tri_nors) ? - r_tri_nors : - MEM_calloc_arrayN((size_t)looptri_num, sizeof(*fnors), "meshnormals"); + float(*tnorms)[3] = (float(*)[3])MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms"); + float(*fnors)[3] = (r_tri_nors) ? r_tri_nors : + (float(*)[3])MEM_calloc_arrayN( + (size_t)looptri_num, sizeof(*fnors), "meshnormals"); if (!tnorms || !fnors) { goto cleanup; @@ -519,9 +519,10 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, lnors_spacearr->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); } mem = lnors_spacearr->mem; - lnors_spacearr->lspacearr = BLI_memarena_calloc(mem, - sizeof(MLoopNorSpace *) * (size_t)numLoops); - lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops); + lnors_spacearr->lspacearr = (MLoopNorSpace **)BLI_memarena_calloc( + mem, sizeof(MLoopNorSpace *) * (size_t)numLoops); + lnors_spacearr->loops_pool = (LinkNode *)BLI_memarena_alloc( + mem, sizeof(LinkNode) * (size_t)numLoops); lnors_spacearr->num_spaces = 0; } @@ -532,9 +533,9 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) { lnors_spacearr->num_spaces = 0; - lnors_spacearr->lspacearr = NULL; - lnors_spacearr->loops_pool = NULL; - if (lnors_spacearr->mem != NULL) { + lnors_spacearr->lspacearr = nullptr; + lnors_spacearr->loops_pool = nullptr; + if (lnors_spacearr->mem != nullptr) { BLI_memarena_clear(lnors_spacearr->mem); } } @@ -542,16 +543,16 @@ void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr) { lnors_spacearr->num_spaces = 0; - lnors_spacearr->lspacearr = NULL; - lnors_spacearr->loops_pool = NULL; + lnors_spacearr->lspacearr = nullptr; + lnors_spacearr->loops_pool = nullptr; BLI_memarena_free(lnors_spacearr->mem); - lnors_spacearr->mem = NULL; + lnors_spacearr->mem = nullptr; } MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr) { lnors_spacearr->num_spaces++; - return BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace)); + return (MLoopNorSpace *)BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace)); } /* This threshold is a bit touchy (usual float precision issue), this value seems OK. */ @@ -592,7 +593,7 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, float alpha = 0.0f; int nbr = 0; while (!BLI_stack_is_empty(edge_vectors)) { - const float *vec = BLI_stack_peek(edge_vectors); + const float *vec = (const float *)BLI_stack_peek(edge_vectors); alpha += saacosf(dot_v3v3(vec, lnor)); BLI_stack_discard(edge_vectors); nbr++; @@ -637,10 +638,10 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, /** * Add a new given loop to given lnor_space. * Depending on \a lnor_space->data_type, we expect \a bm_loop to be a pointer to BMLoop struct - * (in case of BMLOOP_PTR), or NULL (in case of LOOP_INDEX), loop index is then stored in pointer. - * If \a is_single is set, the BMLoop or loop index is directly stored in \a lnor_space->loops - * pointer (since there is only one loop in this fan), - * else it is added to the linked list of loops in the fan. + * (in case of BMLOOP_PTR), or nullptr (in case of LOOP_INDEX), loop index is then stored in + * pointer. If \a is_single is set, the BMLoop or loop index is directly stored in \a + * lnor_space->loops pointer (since there is only one loop in this fan), else it is added to the + * linked list of loops in the fan. */ void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, @@ -648,17 +649,17 @@ void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, void *bm_loop, const bool is_single) { - BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == NULL) || - (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != NULL)); + BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == nullptr) || + (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != nullptr)); lnors_spacearr->lspacearr[ml_index] = lnor_space; - if (bm_loop == NULL) { + if (bm_loop == nullptr) { bm_loop = POINTER_FROM_INT(ml_index); } if (is_single) { - BLI_assert(lnor_space->loops == NULL); + BLI_assert(lnor_space->loops == nullptr); lnor_space->flags |= MLNOR_SPACE_IS_SINGLE; - lnor_space->loops = bm_loop; + lnor_space->loops = (LinkNode *)bm_loop; } else { BLI_assert((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0); @@ -715,7 +716,8 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2]) { - /* We use null vector as NOP custom normal (can be simpler than giving auto-computed `lnor`). */ + /* We use nullptr vector as NOP custom normal (can be simpler than giving auto-computed `lnor`). + */ if (is_zero_v3(custom_lnor) || compare_v3v3(lnor_space->vec_lnor, custom_lnor, 1e-4f)) { r_clnor_data[0] = r_clnor_data[1] = 0; return; @@ -765,7 +767,7 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, #define LOOP_SPLIT_TASK_BLOCK_SIZE 1024 -typedef struct LoopSplitTaskData { +struct LoopSplitTaskData { /* Specific to each instance (each task). */ /** We have to create those outside of tasks, since #MemArena is not thread-safe. */ @@ -784,9 +786,9 @@ typedef struct LoopSplitTaskData { BLI_Stack *edge_vectors; char pad_c; -} LoopSplitTaskData; +}; -typedef struct LoopSplitTaskDataCommon { +struct LoopSplitTaskDataCommon { /* Read/write. * Note we do not need to protect it, though, since two different tasks will *always* affect * different elements in the arrays. */ @@ -806,7 +808,7 @@ typedef struct LoopSplitTaskDataCommon { int numEdges; int numLoops; int numPolys; -} LoopSplitTaskDataCommon; +}; #define INDEX_UNSET INT_MIN #define INDEX_INVALID -1 @@ -827,13 +829,13 @@ static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data, const int numEdges = data->numEdges; const int numPolys = data->numPolys; - float(*loopnors)[3] = data->loopnors; /* NOTE: loopnors may be NULL here. */ + float(*loopnors)[3] = data->loopnors; /* NOTE: loopnors may be nullptr here. */ const float(*polynors)[3] = data->polynors; int(*edge_to_loops)[2] = data->edge_to_loops; int *loop_to_poly = data->loop_to_poly; - BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : NULL; + BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : nullptr; const MPoly *mp; int mp_index; @@ -943,22 +945,22 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts, } /* Mapping edge -> loops. See BKE_mesh_normals_loop_split() for details. */ - int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__); + int(*edge_to_loops)[2] = (int(*)[2])MEM_calloc_arrayN( + (size_t)numEdges, sizeof(*edge_to_loops), __func__); /* Simple mapping from a loop to its polygon index. */ - int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); - - LoopSplitTaskDataCommon common_data = { - .mverts = mverts, - .medges = medges, - .mloops = mloops, - .mpolys = mpolys, - .edge_to_loops = edge_to_loops, - .loop_to_poly = loop_to_poly, - .polynors = polynors, - .numEdges = numEdges, - .numPolys = numPolys, - }; + int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + + LoopSplitTaskDataCommon common_data; + common_data.mverts = mverts; + common_data.medges = medges; + common_data.mloops = mloops; + common_data.mpolys = mpolys; + common_data.edge_to_loops = edge_to_loops; + common_data.loop_to_poly = loop_to_poly; + common_data.polynors = polynors; + common_data.numEdges = numEdges; + common_data.numPolys = numPolys; mesh_edges_sharp_tag(&common_data, true, split_angle, true); @@ -1065,10 +1067,10 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co); normalize_v3(vec_prev); - BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, NULL); + BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, nullptr); /* We know there is only one loop in this space, * no need to create a linklist in this case... */ - BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, NULL, true); + BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, nullptr, true); if (clnors_data) { BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor); @@ -1125,7 +1127,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* We validate clnors data on the fly - cheapest way to do! */ int clnors_avg[2] = {0, 0}; - short(*clnor_ref)[2] = NULL; + short(*clnor_ref)[2] = nullptr; int clnors_nbr = 0; bool clnors_invalid = false; @@ -1205,7 +1207,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (lnors_spacearr) { /* Assign current lnor space to current 'vertex' loop. */ - BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, NULL, false); + BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, nullptr, false); if (me_curr != me_org) { /* We store here all edges-normalized vectors processed. */ BLI_stack_push(edge_vectors, vec_curr); @@ -1261,7 +1263,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (G.debug & G_DEBUG) { printf("Invalid clnors in this fan!\n"); } - while ((clnor = BLI_SMALLSTACK_POP(clnors))) { + while ((clnor = (short *)BLI_SMALLSTACK_POP(clnors))) { // print_v2("org clnor", clnor); clnor[0] = (short)clnors_avg[0]; clnor[1] = (short)clnors_avg[1]; @@ -1280,7 +1282,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* Copy back the final computed normal into all related loop-normals. */ float *nor; - while ((nor = BLI_SMALLSTACK_POP(normal))) { + while ((nor = (float *)BLI_SMALLSTACK_POP(normal))) { copy_v3_v3(nor, lnor); } } @@ -1295,7 +1297,7 @@ static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, { BLI_assert(data->ml_curr); if (data->e2l_prev) { - BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors)); + BLI_assert((edge_vectors == nullptr) || BLI_stack_is_empty(edge_vectors)); data->edge_vectors = edge_vectors; split_loop_nor_fan_do(common_data, data); } @@ -1307,21 +1309,21 @@ static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, static void loop_split_worker(TaskPool *__restrict pool, void *taskdata) { - LoopSplitTaskDataCommon *common_data = BLI_task_pool_user_data(pool); - LoopSplitTaskData *data = taskdata; + LoopSplitTaskDataCommon *common_data = (LoopSplitTaskDataCommon *)BLI_task_pool_user_data(pool); + LoopSplitTaskData *data = (LoopSplitTaskData *)taskdata; /* Temp edge vectors stack, only used when computing lnor spacearr. */ BLI_Stack *edge_vectors = common_data->lnors_spacearr ? BLI_stack_new(sizeof(float[3]), __func__) : - NULL; + nullptr; #ifdef DEBUG_TIME TIMEIT_START_AVERAGED(loop_split_worker); #endif for (int i = 0; i < LOOP_SPLIT_TASK_BLOCK_SIZE; i++, data++) { - /* A NULL ml_curr is used to tag ended data! */ - if (data->ml_curr == NULL) { + /* A nullptr ml_curr is used to tag ended data! */ + if (data->ml_curr == nullptr) { break; } @@ -1434,12 +1436,12 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common BLI_bitmap *skip_loops = BLI_BITMAP_NEW(numLoops, __func__); - LoopSplitTaskData *data_buff = NULL; + LoopSplitTaskData *data_buff = nullptr; int data_idx = 0; /* Temp edge vectors stack, only used when computing lnor spacearr * (and we are not multi-threading). */ - BLI_Stack *edge_vectors = NULL; + BLI_Stack *edge_vectors = nullptr; #ifdef DEBUG_TIME TIMEIT_START_AVERAGED(loop_split_generator); @@ -1508,7 +1510,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common if (pool) { if (data_idx == 0) { - data_buff = MEM_calloc_arrayN( + data_buff = (LoopSplitTaskData *)MEM_calloc_arrayN( LOOP_SPLIT_TASK_BLOCK_SIZE, sizeof(*data_buff), __func__); } data = &data_buff[data_idx]; @@ -1525,7 +1527,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common data->ml_curr_index = ml_curr_index; #if 0 /* Not needed for 'single' loop. */ data->ml_prev_index = ml_prev_index; - data->e2l_prev = NULL; /* Tag as 'single' task. */ + data->e2l_prev = nullptr; /* Tag as 'single' task. */ #endif data->mp_index = mp_index; if (lnors_spacearr) { @@ -1559,7 +1561,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common if (pool) { data_idx++; if (data_idx == LOOP_SPLIT_TASK_BLOCK_SIZE) { - BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL); + BLI_task_pool_push(pool, loop_split_worker, data_buff, true, nullptr); data_idx = 0; } } @@ -1573,10 +1575,10 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common } } - /* Last block of data... Since it is calloc'ed and we use first NULL item as stopper, + /* Last block of data... Since it is calloc'ed and we use first nullptr item as stopper, * everything is fine. */ if (pool && data_idx) { - BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL); + BLI_task_pool_push(pool, loop_split_worker, data_buff, true, nullptr); } if (edge_vectors) { @@ -1659,17 +1661,18 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, * However, if needed, we can store the negated value of loop index instead of INDEX_INVALID * to retrieve the real value later in code). * Note also that loose edges always have both values set to 0! */ - int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__); + int(*edge_to_loops)[2] = (int(*)[2])MEM_calloc_arrayN( + (size_t)numEdges, sizeof(*edge_to_loops), __func__); /* Simple mapping from a loop to its polygon index. */ - int *loop_to_poly = r_loop_to_poly ? - r_loop_to_poly : - MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + int *loop_to_poly = r_loop_to_poly ? r_loop_to_poly : + (int *)MEM_malloc_arrayN( + (size_t)numLoops, sizeof(*loop_to_poly), __func__); /* When using custom loop normals, disable the angle feature! */ - const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == NULL); + const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == nullptr); - MLoopNorSpaceArray _lnors_spacearr = {NULL}; + MLoopNorSpaceArray _lnors_spacearr = {nullptr}; #ifdef DEBUG_TIME TIMEIT_START_AVERAGED(BKE_mesh_normals_loop_split); @@ -1684,28 +1687,27 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, } /* Init data common to all tasks. */ - LoopSplitTaskDataCommon common_data = { - .lnors_spacearr = r_lnors_spacearr, - .loopnors = r_loopnors, - .clnors_data = clnors_data, - .mverts = mverts, - .medges = medges, - .mloops = mloops, - .mpolys = mpolys, - .edge_to_loops = edge_to_loops, - .loop_to_poly = loop_to_poly, - .polynors = polynors, - .numEdges = numEdges, - .numLoops = numLoops, - .numPolys = numPolys, - }; + LoopSplitTaskDataCommon common_data; + common_data.lnors_spacearr = r_lnors_spacearr; + common_data.loopnors = r_loopnors; + common_data.clnors_data = clnors_data; + common_data.mverts = mverts; + common_data.medges = medges; + common_data.mloops = mloops; + common_data.mpolys = mpolys; + common_data.edge_to_loops = edge_to_loops; + common_data.loop_to_poly = loop_to_poly; + common_data.polynors = polynors; + common_data.numEdges = numEdges; + common_data.numLoops = numLoops; + common_data.numPolys = numPolys; /* This first loop check which edges are actually smooth, and compute edge vectors. */ mesh_edges_sharp_tag(&common_data, check_angle, split_angle, false); if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) { /* Not enough loops to be worth the whole threading overhead... */ - loop_split_generator(NULL, &common_data); + loop_split_generator(nullptr, &common_data); } else { TaskPool *task_pool = BLI_task_pool_create(&common_data, TASK_PRIORITY_HIGH); @@ -1766,10 +1768,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, * (and perhaps from some editing tools later?). * So better to keep some simplicity here, and just call BKE_mesh_normals_loop_split() twice! */ - MLoopNorSpaceArray lnors_spacearr = {NULL}; + MLoopNorSpaceArray lnors_spacearr = {nullptr}; BLI_bitmap *done_loops = BLI_BITMAP_NEW((size_t)numLoops, __func__); - float(*lnors)[3] = MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__); - int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__); + float(*lnors)[3] = (float(*)[3])MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__); + int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__); /* In this case we always consider split nors as ON, * and do not want to use angle to define smooth fans! */ const bool use_split_normals = true; @@ -1791,7 +1793,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, use_split_normals, split_angle, &lnors_spacearr, - NULL, + nullptr, loop_to_poly); /* Set all given zero vectors to their default value. */ @@ -1823,12 +1825,12 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, for (int i = 0; i < numLoops; i++) { if (!lnors_spacearr.lspacearr[i]) { /* This should not happen in theory, but in some rare case (probably ugly geometry) - * we can get some NULL loopspacearr at this point. :/ + * we can get some nullptr loopspacearr at this point. :/ * Maybe we should set those loops' edges as sharp? */ BLI_BITMAP_ENABLE(done_loops, i); if (G.debug & G_DEBUG) { - printf("WARNING! Getting invalid NULL loop space for loop %d!\n", i); + printf("WARNING! Getting invalid nullptr loop space for loop %d!\n", i); } continue; } @@ -1849,8 +1851,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, } LinkNode *loops = lnors_spacearr.lspacearr[i]->loops; - MLoop *prev_ml = NULL; - const float *org_nor = NULL; + MLoop *prev_ml = nullptr; + const float *org_nor = nullptr; while (loops) { const int lidx = POINTER_AS_INT(loops->link); @@ -1916,7 +1918,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, use_split_normals, split_angle, &lnors_spacearr, - NULL, + nullptr, loop_to_poly); } else { @@ -1929,7 +1931,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, if (!lnors_spacearr.lspacearr[i]) { BLI_BITMAP_DISABLE(done_loops, i); if (G.debug & G_DEBUG) { - printf("WARNING! Still getting invalid NULL loop space in second loop for loop %d!\n", i); + printf("WARNING! Still getting invalid nullptr loop space in second loop for loop %d!\n", + i); } continue; } @@ -1970,7 +1973,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors); BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp); - while ((clnor_data = BLI_SMALLSTACK_POP(clnors_data))) { + while ((clnor_data = (short *)BLI_SMALLSTACK_POP(clnors_data))) { clnor_data[0] = clnor_data_tmp[0]; clnor_data[1] = clnor_data_tmp[1]; } @@ -2041,20 +2044,21 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const short(*clnors)[2]; const int numloops = mesh->totloop; - clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); - if (clnors != NULL) { + clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + if (clnors != nullptr) { memset(clnors, 0, sizeof(*clnors) * (size_t)numloops); } else { - clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numloops); + clnors = (short(*)[2])CustomData_add_layer( + &mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, nullptr, numloops); } - float(*polynors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + float(*polynors)[3] = (float(*)[3])CustomData_get_layer(&mesh->pdata, CD_NORMAL); bool free_polynors = false; - if (polynors == NULL) { - polynors = MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__); + if (polynors == nullptr) { + polynors = (float(*)[3])MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__); BKE_mesh_calc_normals_poly(mesh->mvert, - NULL, + nullptr, mesh->totvert, mesh->mloop, mesh->mpoly, @@ -2119,7 +2123,8 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts, const float (*clnors)[3], float (*r_vert_clnors)[3]) { - int *vert_loops_nbr = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vert_loops_nbr), __func__); + int *vert_loops_nbr = (int *)MEM_calloc_arrayN( + (size_t)numVerts, sizeof(*vert_loops_nbr), __func__); copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index bf18765aa94..7e524da0f53 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -631,10 +631,10 @@ float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode) { NlaStrip *strip; - /* sanity checks - * - obviously we've got to have some starting data - * - when not in tweakmode, the active Action does not have any scaling applied :) - * - when in tweakmode, if the no-mapping flag is set, do not map + /* Sanity checks: + * - Obviously we've got to have some starting data. + * - When not in tweak-mode, the active Action does not have any scaling applied :) + * - When in tweak-mode, if the no-mapping flag is set, do not map. */ if ((adt == NULL) || (adt->flag & ADT_NLA_EDIT_ON) == 0 || (adt->flag & ADT_NLA_EDIT_NOMAP)) { return cframe; @@ -2089,9 +2089,8 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) return false; } - /* if block is already in tweakmode, just leave, but we should report - * that this block is in tweakmode (as our returncode) - */ + /* If block is already in tweak-mode, just leave, but we should report + * that this block is in tweak-mode (as our returncode). */ if (adt->flag & ADT_NLA_EDIT_ON) { return true; } @@ -2111,8 +2110,8 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) } } - /* There are situations where we may have multiple strips selected and we want to enter tweakmode - * on all of those at once. Usually in those cases, + /* There are situations where we may have multiple strips selected and we want to enter + * tweak-mode on all of those at once. Usually in those cases, * it will usually just be a single strip per AnimData. * In such cases, compromise and take the last selected track and/or last selected strip, T28468. */ @@ -2142,7 +2141,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) if (ELEM(NULL, activeTrack, activeStrip, activeStrip->act)) { if (G.debug & G_DEBUG) { - printf("NLA tweakmode enter - neither active requirement found\n"); + printf("NLA tweak-mode enter - neither active requirement found\n"); printf("\tactiveTrack = %p, activeStrip = %p\n", (void *)activeTrack, (void *)activeStrip); } return false; @@ -2192,7 +2191,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) return true; } -/* Exit tweakmode for this AnimData block */ +/* Exit tweak-mode for this AnimData block. */ void BKE_nla_tweakmode_exit(AnimData *adt) { NlaStrip *strip; diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index f6105bac1a8..e4c259ec9fc 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -69,7 +69,6 @@ #include "BKE_lib_query.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_node_ui_storage.hh" #include "BLI_ghash.h" #include "BLI_threads.h" @@ -220,10 +219,6 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c /* node tree will generate its own interface type */ ntree_dst->interface_type = nullptr; - - /* Don't copy error messages in the runtime struct. - * They should be filled during execution anyway. */ - ntree_dst->ui_storage = nullptr; } static void ntree_free_data(ID *id) @@ -277,8 +272,6 @@ static void ntree_free_data(ID *id) if (ntree->id.tag & LIB_TAG_LOCALIZED) { BKE_libblock_free_data(&ntree->id, true); } - - delete ntree->ui_storage; } static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock) @@ -621,7 +614,6 @@ static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_addres ntree->interface_type = nullptr; ntree->progress = nullptr; ntree->execdata = nullptr; - ntree->ui_storage = nullptr; BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id); @@ -653,7 +645,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree) ntree->progress = nullptr; ntree->execdata = nullptr; - ntree->ui_storage = nullptr; BLO_read_data_address(reader, &ntree->adt); BKE_animdata_blend_read_data(reader, ntree->adt); @@ -1425,6 +1416,12 @@ GHashIterator *nodeSocketTypeGetIterator(void) return BLI_ghashIterator_new(nodesockettypes_hash); } +const char *nodeSocketTypeLabel(const bNodeSocketType *stype) +{ + /* Use socket type name as a fallback if label is undefined. */ + return stype->label[0] != '\0' ? stype->label : RNA_struct_ui_name(stype->ext_socket.srna); +} + struct bNodeSocket *nodeFindSocket(const bNode *node, eNodeSocketInOut in_out, const char *identifier) @@ -1585,13 +1582,15 @@ static void socket_id_user_decrement(bNodeSocket *sock) } } -void nodeModifySocketType( - bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, int type, int subtype) +void nodeModifySocketType(bNodeTree *ntree, + bNode *UNUSED(node), + bNodeSocket *sock, + const char *idname) { - const char *idname = nodeStaticSocketType(type, subtype); + bNodeSocketType *socktype = nodeSocketTypeFind(idname); - if (!idname) { - CLOG_ERROR(&LOG, "static node socket type %d undefined", type); + if (!socktype) { + CLOG_ERROR(&LOG, "node socket type %s undefined", idname); return; } @@ -1601,9 +1600,21 @@ void nodeModifySocketType( sock->default_value = nullptr; } - sock->type = type; BLI_strncpy(sock->idname, idname, sizeof(sock->idname)); - node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(idname)); + node_socket_set_typeinfo(ntree, sock, socktype); +} + +void nodeModifySocketTypeStatic( + bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype) +{ + const char *idname = nodeStaticSocketType(type, subtype); + + if (!idname) { + CLOG_ERROR(&LOG, "static node socket type %d undefined", type); + return; + } + + nodeModifySocketType(ntree, node, sock, idname); } bNodeSocket *nodeAddSocket(bNodeTree *ntree, @@ -1647,6 +1658,15 @@ bNodeSocket *nodeInsertSocket(bNodeTree *ntree, return sock; } +bool nodeIsStaticSocketType(const struct bNodeSocketType *stype) +{ + /* + * Cannot rely on type==SOCK_CUSTOM here, because type is 0 by default + * and can be changed on custom sockets. + */ + return RNA_struct_is_a(stype->ext_socket.srna, &RNA_NodeSocketStandard); +} + const char *nodeStaticSocketType(int type, int subtype) { switch (type) { @@ -1801,6 +1821,39 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype) return nullptr; } +const char *nodeStaticSocketLabel(int type, int UNUSED(subtype)) +{ + switch (type) { + case SOCK_FLOAT: + return "Float"; + case SOCK_INT: + return "Integer"; + case SOCK_BOOLEAN: + return "Boolean"; + case SOCK_VECTOR: + return "Vector"; + case SOCK_RGBA: + return "Color"; + case SOCK_STRING: + return "String"; + case SOCK_SHADER: + return "Shader"; + case SOCK_OBJECT: + return "Object"; + case SOCK_IMAGE: + return "Image"; + case SOCK_GEOMETRY: + return "Geometry"; + case SOCK_COLLECTION: + return "Collection"; + case SOCK_TEXTURE: + return "Texture"; + case SOCK_MATERIAL: + return "Material"; + } + return nullptr; +} + bNodeSocket *nodeAddStaticSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, @@ -5044,27 +5097,29 @@ static void registerGeometryNodes() register_node_type_geo_attribute_mix(); register_node_type_geo_attribute_proximity(); register_node_type_geo_attribute_randomize(); + register_node_type_geo_attribute_remove(); register_node_type_geo_attribute_separate_xyz(); register_node_type_geo_attribute_transfer(); register_node_type_geo_attribute_vector_math(); register_node_type_geo_attribute_vector_rotate(); - register_node_type_geo_attribute_remove(); register_node_type_geo_boolean(); register_node_type_geo_bounding_box(); register_node_type_geo_collection_info(); register_node_type_geo_convex_hull(); + register_node_type_geo_curve_endpoints(); register_node_type_geo_curve_length(); register_node_type_geo_curve_primitive_bezier_segment(); register_node_type_geo_curve_primitive_circle(); register_node_type_geo_curve_primitive_line(); register_node_type_geo_curve_primitive_quadratic_bezier(); + register_node_type_geo_curve_primitive_quadrilateral(); register_node_type_geo_curve_primitive_spiral(); register_node_type_geo_curve_primitive_star(); - register_node_type_geo_curve_to_mesh(); - register_node_type_geo_curve_to_points(); register_node_type_geo_curve_resample(); register_node_type_geo_curve_reverse(); register_node_type_geo_curve_subdivide(); + register_node_type_geo_curve_to_mesh(); + register_node_type_geo_curve_to_points(); register_node_type_geo_delete_geometry(); register_node_type_geo_edge_split(); register_node_type_geo_input_material(); @@ -5080,6 +5135,7 @@ static void registerGeometryNodes() register_node_type_geo_mesh_primitive_ico_sphere(); register_node_type_geo_mesh_primitive_line(); register_node_type_geo_mesh_primitive_uv_sphere(); + register_node_type_geo_mesh_subdivide(); register_node_type_geo_mesh_to_curve(); register_node_type_geo_object_info(); register_node_type_geo_point_distribute(); @@ -5093,7 +5149,6 @@ static void registerGeometryNodes() register_node_type_geo_sample_texture(); register_node_type_geo_select_by_material(); register_node_type_geo_separate_components(); - register_node_type_geo_subdivide(); register_node_type_geo_subdivision_surface(); register_node_type_geo_switch(); register_node_type_geo_transform(); diff --git a/source/blender/blenkernel/intern/node_ui_storage.cc b/source/blender/blenkernel/intern/node_ui_storage.cc deleted file mode 100644 index e5e9f00c7c3..00000000000 --- a/source/blender/blenkernel/intern/node_ui_storage.cc +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "CLG_log.h" - -#include <mutex> - -#include "BLI_map.hh" -#include "BLI_string_ref.hh" -#include "BLI_vector.hh" - -#include "DNA_node_types.h" -#include "DNA_object_types.h" - -#include "BKE_context.h" -#include "BKE_node_ui_storage.hh" -#include "BKE_object.h" - -static CLG_LogRef LOG = {"bke.node_ui_storage"}; - -using blender::Map; -using blender::StringRef; -using blender::Vector; - -/* Use a global mutex because otherwise it would have to be stored directly in the - * bNodeTree struct in DNA. This could change if the node tree had a runtime struct. */ -static std::mutex global_ui_storage_mutex; - -static NodeTreeUIStorage &ui_storage_ensure(bNodeTree &ntree) -{ - /* As an optimization, only acquire a lock if the UI storage doesn't exist, - * because it only needs to be allocated once for every node tree. */ - if (ntree.ui_storage == nullptr) { - std::lock_guard<std::mutex> lock(global_ui_storage_mutex); - /* Check again-- another thread may have allocated the storage while this one waited. */ - if (ntree.ui_storage == nullptr) { - ntree.ui_storage = new NodeTreeUIStorage(); - } - } - return *ntree.ui_storage; -} - -const NodeUIStorage *BKE_node_tree_ui_storage_get_from_context(const bContext *C, - const bNodeTree &ntree, - const bNode &node) -{ - const NodeTreeUIStorage *ui_storage = ntree.ui_storage; - if (ui_storage == nullptr) { - return nullptr; - } - - const Object *active_object = CTX_data_active_object(C); - if (active_object == nullptr) { - return nullptr; - } - - const ModifierData *active_modifier = BKE_object_active_modifier(active_object); - if (active_modifier == nullptr) { - return nullptr; - } - - const NodeTreeEvaluationContext context(*active_object, *active_modifier); - const Map<std::string, NodeUIStorage> *storage = ui_storage->context_map.lookup_ptr(context); - if (storage == nullptr) { - return nullptr; - } - - return storage->lookup_ptr_as(StringRef(node.name)); -} - -/** - * Removes only the UI data associated with a particular evaluation context. The same node tree - * can be used for execution in multiple places, but the entire UI storage can't be removed when - * one execution starts, or all of the data associated with the node tree would be lost. - */ -void BKE_nodetree_ui_storage_free_for_context(bNodeTree &ntree, - const NodeTreeEvaluationContext &context) -{ - NodeTreeUIStorage *ui_storage = ntree.ui_storage; - if (ui_storage != nullptr) { - std::lock_guard<std::mutex> lock(ui_storage->mutex); - ui_storage->context_map.remove(context); - } -} - -static void node_error_message_log(bNodeTree &ntree, - const bNode &node, - const StringRef message, - const NodeWarningType type) -{ - switch (type) { - case NodeWarningType::Error: - CLOG_ERROR(&LOG, - "Node Tree: \"%s\", Node: \"%s\", %s", - ntree.id.name + 2, - node.name, - message.data()); - break; - case NodeWarningType::Warning: - CLOG_WARN(&LOG, - "Node Tree: \"%s\", Node: \"%s\", %s", - ntree.id.name + 2, - node.name, - message.data()); - break; - case NodeWarningType::Info: - CLOG_INFO(&LOG, - 2, - "Node Tree: \"%s\", Node: \"%s\", %s", - ntree.id.name + 2, - node.name, - message.data()); - break; - } -} - -static NodeUIStorage &node_ui_storage_ensure(NodeTreeUIStorage &locked_ui_storage, - const NodeTreeEvaluationContext &context, - const bNode &node) -{ - Map<std::string, NodeUIStorage> &node_tree_ui_storage = - locked_ui_storage.context_map.lookup_or_add_default(context); - NodeUIStorage &node_ui_storage = node_tree_ui_storage.lookup_or_add_default_as( - StringRef(node.name)); - return node_ui_storage; -} - -void BKE_nodetree_error_message_add(bNodeTree &ntree, - const NodeTreeEvaluationContext &context, - const bNode &node, - const NodeWarningType type, - std::string message) -{ - NodeTreeUIStorage &ui_storage = ui_storage_ensure(ntree); - std::lock_guard lock{ui_storage.mutex}; - - node_error_message_log(ntree, node, message, type); - - NodeUIStorage &node_ui_storage = node_ui_storage_ensure(ui_storage, context, node); - node_ui_storage.warnings.append({type, std::move(message)}); -} - -void BKE_nodetree_attribute_hint_add(bNodeTree &ntree, - const NodeTreeEvaluationContext &context, - const bNode &node, - const StringRef attribute_name, - const AttributeDomain domain, - const CustomDataType data_type) -{ - NodeTreeUIStorage &ui_storage = ui_storage_ensure(ntree); - std::lock_guard lock{ui_storage.mutex}; - - NodeUIStorage &node_ui_storage = node_ui_storage_ensure(ui_storage, context, node); - node_ui_storage.attribute_hints.add_as( - AvailableAttributeInfo{attribute_name, domain, data_type}); -} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a13feafb70b..912b5e0a0dd 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1753,10 +1753,6 @@ void BKE_object_free_derived_caches(Object *ob) BKE_geometry_set_free(ob->runtime.geometry_set_eval); ob->runtime.geometry_set_eval = NULL; } - if (ob->runtime.geometry_set_previews != NULL) { - BLI_ghash_free(ob->runtime.geometry_set_previews, NULL, (GHashValFreeFP)BKE_geometry_set_free); - ob->runtime.geometry_set_previews = NULL; - } } void BKE_object_free_caches(Object *object) @@ -1807,24 +1803,6 @@ void BKE_object_free_caches(Object *object) } } -/* Can be called from multiple threads. */ -void BKE_object_preview_geometry_set_add(Object *ob, - const uint64_t key, - struct GeometrySet *geometry_set) -{ - static ThreadMutex mutex = BLI_MUTEX_INITIALIZER; - BLI_mutex_lock(&mutex); - if (ob->runtime.geometry_set_previews == NULL) { - ob->runtime.geometry_set_previews = BLI_ghash_int_new(__func__); - } - BLI_ghash_reinsert(ob->runtime.geometry_set_previews, - POINTER_FROM_UINT(key), - geometry_set, - NULL, - (GHashValFreeFP)BKE_geometry_set_free); - BLI_mutex_unlock(&mutex); -} - /** * Actual check for internal data, not context or flags. */ @@ -2828,7 +2806,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target) /* add new animdata block */ if (!ob->adt) { - ob->adt = BKE_animdata_add_id(&ob->id); + ob->adt = BKE_animdata_ensure_id(&ob->id); } /* make a copy of all the drivers (for now), then correct any links that need fixing */ @@ -4155,6 +4133,30 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph, return ok; } +struct GPencilStrokePointIterData { + const float (*obmat)[4]; + + void (*point_func_cb)(const float co[3], void *user_data); + void *user_data; +}; + +static void foreach_display_point_gpencil_stroke_fn(bGPDlayer *UNUSED(layer), + bGPDframe *UNUSED(frame), + bGPDstroke *stroke, + void *thunk) +{ + struct GPencilStrokePointIterData *iter_data = thunk; + { + bGPDspoint *pt; + int i; + for (i = 0, pt = stroke->points; i < stroke->totpoints; i++, pt++) { + float co[3]; + mul_v3_m4v3(co, iter_data->obmat, &pt->x); + iter_data->point_func_cb(co, iter_data->user_data); + } + } +} + void BKE_object_foreach_display_point(Object *ob, const float obmat[4][4], void (*func_cb)(const float[3], void *), @@ -4172,6 +4174,13 @@ void BKE_object_foreach_display_point(Object *ob, func_cb(co, user_data); } } + else if (ob->type == OB_GPENCIL) { + struct GPencilStrokePointIterData iter_data = { + .obmat = obmat, .point_func_cb = func_cb, .user_data = user_data}; + + BKE_gpencil_visible_stroke_iter( + ob->data, NULL, foreach_display_point_gpencil_stroke_fn, &iter_data); + } else if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first) { DispList *dl; diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index ab247ef5507..7cdea14e9bd 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -123,7 +123,7 @@ void BKE_object_eval_parent(Depsgraph *depsgraph, Object *ob) void BKE_object_eval_constraints(Depsgraph *depsgraph, Scene *scene, Object *ob) { bConstraintOb *cob; - float ctime = BKE_scene_frame_get(scene); + float ctime = BKE_scene_ctime_get(scene); DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); @@ -388,12 +388,31 @@ void BKE_object_batch_cache_dirty_tag(Object *ob) BKE_object_data_batch_cache_dirty_tag(ob->data); } +void BKE_object_data_eval_batch_cache_dirty_tag(Depsgraph *depsgraph, ID *object_data) +{ + DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data); + BKE_object_data_batch_cache_dirty_tag(object_data); +} + +void BKE_object_data_eval_batch_cache_deform_tag(Depsgraph *depsgraph, ID *object_data) +{ + DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data); + switch (GS(object_data->name)) { + case ID_ME: + BKE_mesh_batch_cache_dirty_tag((Mesh *)object_data, BKE_MESH_BATCH_DIRTY_DEFORM); + break; + default: + /* Only mesh is currently supported. Fallback to dirty all for other datablocks types. */ + BKE_object_data_batch_cache_dirty_tag(object_data); + break; + } +} + void BKE_object_eval_uber_data(Depsgraph *depsgraph, Scene *scene, Object *ob) { DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); BLI_assert(ob->type != OB_ARMATURE); BKE_object_handle_data_update(depsgraph, scene, ob); - BKE_object_batch_cache_dirty_tag(ob); } void BKE_object_eval_ptcache_reset(Depsgraph *depsgraph, Scene *scene, Object *object) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 7504fbeed19..db1fbb56125 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3961,7 +3961,7 @@ static ModifierData *object_add_or_copy_particle_system( psys->totpart = 0; psys->flag = PSYS_CURRENT; if (scene != NULL) { - psys->cfra = BKE_scene_frame_to_ctime(scene, CFRA + 1); + psys->cfra = BKE_scene_frame_to_ctime(scene, scene->r.cfra + 1); } DEG_relations_tag_update(bmain); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 18b4c72932d..1f8f9ce63ac 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -2157,7 +2157,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, const float *co[3]; if (origco) { - /* intersect with backuped original coordinates */ + /* Intersect with backed up original coordinates. */ co[0] = origco[face_verts[0]]; co[1] = origco[face_verts[1]]; co[2] = origco[face_verts[2]]; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 90018e64f78..9ed5b0230e6 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2807,8 +2807,8 @@ void BKE_ptcache_id_time( cache = pid->cache; if (timescale) { - time = BKE_scene_frame_get(scene); - nexttime = BKE_scene_frame_to_ctime(scene, CFRA + 1.0f); + time = BKE_scene_ctime_get(scene); + nexttime = BKE_scene_frame_to_ctime(scene, scene->r.cfra + 1); *timescale = MAX2(nexttime - time, 0.0f); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f8f4d52fcf2..cc5a8536a5a 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2299,10 +2299,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene) return NULL; } - const int cfra = ((scene->r.images == scene->r.framapto) ? - scene->r.cfra : - (int)(scene->r.cfra * - ((float)scene->r.framapto / (float)scene->r.images))); + const int ctime = (int)BKE_scene_ctime_get(scene); int frame = -(MAXFRAME + 1); int min_frame = MAXFRAME + 1; Object *camera = NULL; @@ -2310,11 +2307,11 @@ Object *BKE_scene_camera_switch_find(Scene *scene) LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) { if (m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER) == 0) { - if ((m->frame <= cfra) && (m->frame > frame)) { + if ((m->frame <= ctime) && (m->frame > frame)) { camera = m->camera; frame = m->frame; - if (frame == cfra) { + if (frame == ctime) { break; } } @@ -2396,13 +2393,13 @@ const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame) return best_marker ? best_marker->name : NULL; } -int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int cfra) +int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame) { const int fps = round_db_to_int(FPS * interval_in_seconds); - const int second_prev = cfra - mod_i(cfra, fps); + const int second_prev = frame - mod_i(frame, fps); const int second_next = second_prev + fps; - const int delta_prev = cfra - second_prev; - const int delta_next = second_next - cfra; + const int delta_prev = frame - second_prev; + const int delta_next = second_next - frame; return (delta_prev < delta_next) ? second_prev : second_next; } @@ -2444,16 +2441,17 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce) return true; } -/** - * This function is needed to cope with fractional frames, needed for motion blur & physics. - */ -float BKE_scene_frame_get(const Scene *scene) +/* Return fractional frame number taking into account subframes and time + * remapping. This the time value used by animation, modifiers and physics + * evaluation. */ +float BKE_scene_ctime_get(const Scene *scene) { return BKE_scene_frame_to_ctime(scene, scene->r.cfra); } -/* This function is used to obtain arbitrary fractional frames */ -float BKE_scene_frame_to_ctime(const Scene *scene, const float frame) +/* Convert integer frame number to fractional frame number taking into account + * subframes and time remapping. */ +float BKE_scene_frame_to_ctime(const Scene *scene, const int frame) { float ctime = frame; ctime += scene->r.subframe; @@ -2461,13 +2459,18 @@ float BKE_scene_frame_to_ctime(const Scene *scene, const float frame) return ctime; } -/** - * Sets the frame int/float components. - */ -void BKE_scene_frame_set(struct Scene *scene, double cfra) + +/* Get current fractional frame based on frame and subframe. */ +float BKE_scene_frame_get(const Scene *scene) +{ + return scene->r.cfra + scene->r.subframe; +} + +/* Set current frame and subframe based on a fractional frame. */ +void BKE_scene_frame_set(Scene *scene, float frame) { double intpart; - scene->r.subframe = modf(cfra, &intpart); + scene->r.subframe = modf((double)frame, &intpart); scene->r.cfra = (int)intpart; } @@ -2736,8 +2739,8 @@ void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool cle * edits from callback are properly taken into account. Doing a time update on those would * lose any possible unkeyed changes made by the handler. */ if (pass == 0) { - const float ctime = BKE_scene_frame_get(scene); - DEG_evaluate_on_framechange(depsgraph, ctime); + const float frame = BKE_scene_frame_get(scene); + DEG_evaluate_on_framechange(depsgraph, frame); } else { DEG_evaluate_on_refresh(depsgraph); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index a2809543b95..73658c3184e 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -1734,6 +1734,12 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area) sfile->runtime = NULL; BLO_read_data_address(reader, &sfile->params); BLO_read_data_address(reader, &sfile->asset_params); + if (sfile->params) { + sfile->params->rename_id = NULL; + } + if (sfile->asset_params) { + sfile->asset_params->base_params.rename_id = NULL; + } } else if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index f978e5e8de4..e4e2ed94b41 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3086,7 +3086,7 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, if (sb->solverflags & SBSO_ESTIMATEIPO) { SB_estimate_transform(ob, sb->lcom, sb->lrot, sb->lscale); } - /* inverse matrix is not uptodate... */ + /* Inverse matrix is not up to date. */ invert_m4_m4(ob->imat, ob->obmat); for (a = 0; a < numVerts; a++, bp++) { diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc index aa0d95d4d61..6234cdf87e2 100644 --- a/source/blender/blenkernel/intern/spline_base.cc +++ b/source/blender/blenkernel/intern/spline_base.cc @@ -512,6 +512,10 @@ void Spline::sample_with_index_factors(const GVArray &src, using T = decltype(dummy); const GVArray_Typed<T> src_typed = src.typed<T>(); MutableSpan<T> dst_typed = dst.typed<T>(); + if (src.size() == 1) { + dst_typed.fill(src_typed[0]); + return; + } blender::threading::parallel_for(dst_typed.index_range(), 1024, [&](IndexRange range) { for (const int i : range) { const LookupResult interp = this->lookup_data_from_index_factor(index_factors[i]); diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc index 76d046337c0..ac6f1bd082c 100644 --- a/source/blender/blenkernel/intern/spline_nurbs.cc +++ b/source/blender/blenkernel/intern/spline_nurbs.cc @@ -346,7 +346,10 @@ Span<NURBSpline::BasisCache> NURBSpline::calculate_basis_cache() const const int size = this->size(); const int eval_size = this->evaluated_points_size(); - BLI_assert(this->evaluated_edges_size() > 0); + if (eval_size == 0) { + return {}; + } + basis_cache_.resize(eval_size); const int order = this->order(); diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 4cc2d101b02..dc5162f201e 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -1352,7 +1352,7 @@ static void studiolight_irradiance_preview(uint *icon_buffer, StudioLight *sl) ITER_PIXELS_END; } -void BKE_studiolight_default(SolidLight lights[4], float light_ambient[4]) +void BKE_studiolight_default(SolidLight lights[4], float light_ambient[3]) { copy_v3_fl3(light_ambient, 0.0, 0.0, 0.0); diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c index ef36acdc3d5..179def0a6f2 100644 --- a/source/blender/blenkernel/intern/tracking_region_tracker.c +++ b/source/blender/blenkernel/intern/tracking_region_tracker.c @@ -155,7 +155,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, return tracking_context_get_frame_ibuf(clip, user, clip_flag, keyed_framenr); } -/* Get image buffer which si used as reference for track. */ +/* Get image buffer which is used as reference for track. */ static ImBuf *tracking_context_get_reference_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag, diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index fe2aa701c63..03bd9323f39 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -722,6 +722,24 @@ eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack, } /** + * When reading undo steps for undo/redo, + * some extra checks are needed when so the correct undo step is decoded. + */ +static UndoStep *undosys_step_iter_first(UndoStep *us_reference, const eUndoStepDir undo_dir) +{ + if (us_reference->type->flags & UNDOTYPE_FLAG_DECODE_ACTIVE_STEP) { + /* Reading this step means an undo action reads undo twice. + * This should be avoided where possible, however some undo systems require it. + * + * Redo skips the current state as this represents the currently loaded state. */ + return (undo_dir == -1) ? us_reference : us_reference->next; + } + + /* Typical case, skip reading the current undo step. */ + return (undo_dir == -1) ? us_reference->prev : us_reference->next; +} + +/** * Undo/Redo until the given `us_target` step becomes the active (currently loaded) one. * * \note Unless `us_target` is a 'skipped' one and `use_skip` is true, `us_target` will become the @@ -786,15 +804,10 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, us_target->type->name, undo_dir); - /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), from - * given reference step. - * - * NOTE: Unlike with redo case, where we can expect current active step to fully reflect current - * data status, in undo case we also do reload the active step. - * FIXME: this feels weak, and should probably not be actually needed? Or should also be done in - * redo case? */ + /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), + * from given reference step. */ bool is_processing_extra_skipped_steps = false; - for (UndoStep *us_iter = (undo_dir == -1) ? us_reference : us_reference->next; us_iter != NULL; + for (UndoStep *us_iter = undosys_step_iter_first(us_reference, undo_dir); us_iter != NULL; us_iter = (undo_dir == -1) ? us_iter->prev : us_iter->next) { BLI_assert(us_iter != NULL); diff --git a/source/blender/blenlib/BLI_array_utils.h b/source/blender/blenlib/BLI_array_utils.h index 2847bc960ad..52d41173a0e 100644 --- a/source/blender/blenlib/BLI_array_utils.h +++ b/source/blender/blenlib/BLI_array_utils.h @@ -28,52 +28,53 @@ extern "C" { #endif -void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride); +void _bli_array_reverse(void *arr, uint arr_len, size_t arr_stride); #define BLI_array_reverse(arr, arr_len) _bli_array_reverse(arr, arr_len, sizeof(*(arr))) -void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir); +void _bli_array_wrap(void *arr, uint arr_len, size_t arr_stride, int dir); #define BLI_array_wrap(arr, arr_len, dir) _bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir) -void _bli_array_permute(void *arr, - const unsigned int arr_len, - const size_t arr_stride, - const unsigned int *order, - void *arr_temp); +void _bli_array_permute( + void *arr, const uint arr_len, const size_t arr_stride, const uint *order, void *arr_temp); #define BLI_array_permute(arr, arr_len, order) \ _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, NULL) #define BLI_array_permute_ex(arr, arr_len, order, arr_temp) \ _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, arr_temp) -int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p); +uint _bli_array_deduplicate_ordered(void *arr, uint arr_len, size_t arr_stride); +#define BLI_array_deduplicate_ordered(arr, arr_len) \ + _bli_array_deduplicate_ordered(arr, arr_len, sizeof(*(arr))) + +int _bli_array_findindex(const void *arr, uint arr_len, size_t arr_stride, const void *p); #define BLI_array_findindex(arr, arr_len, p) _bli_array_findindex(arr, arr_len, sizeof(*(arr)), p) -int _bli_array_rfindindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p); +int _bli_array_rfindindex(const void *arr, uint arr_len, size_t arr_stride, const void *p); #define BLI_array_rfindindex(arr, arr_len, p) \ _bli_array_rfindindex(arr, arr_len, sizeof(*(arr)), p) void _bli_array_binary_and( - void *arr, const void *arr_a, const void *arr_b, unsigned int arr_len, size_t arr_stride); + void *arr, const void *arr_a, const void *arr_b, uint arr_len, size_t arr_stride); #define BLI_array_binary_and(arr, arr_a, arr_b, arr_len) \ (CHECK_TYPE_PAIR_INLINE(*(arr), *(arr_a)), \ CHECK_TYPE_PAIR_INLINE(*(arr), *(arr_b)), \ _bli_array_binary_and(arr, arr_a, arr_b, arr_len, sizeof(*(arr)))) void _bli_array_binary_or( - void *arr, const void *arr_a, const void *arr_b, unsigned int arr_len, size_t arr_stride); + void *arr, const void *arr_a, const void *arr_b, uint arr_len, size_t arr_stride); #define BLI_array_binary_or(arr, arr_a, arr_b, arr_len) \ (CHECK_TYPE_PAIR_INLINE(*(arr), *(arr_a)), \ CHECK_TYPE_PAIR_INLINE(*(arr), *(arr_b)), \ _bli_array_binary_or(arr, arr_a, arr_b, arr_len, sizeof(*(arr)))) bool _bli_array_iter_span(const void *arr, - unsigned int arr_len, + uint arr_len, size_t arr_stride, bool use_wrap, bool use_delimit_bounds, bool (*test_fn)(const void *arr_item, void *user_data), void *user_data, - unsigned int span_step[2], - unsigned int *r_span_len); + uint span_step[2], + uint *r_span_len); #define BLI_array_iter_span( \ arr, arr_len, use_wrap, use_delimit_bounds, test_fn, user_data, span_step, r_span_len) \ _bli_array_iter_span(arr, \ @@ -86,7 +87,7 @@ bool _bli_array_iter_span(const void *arr, span_step, \ r_span_len) -bool _bli_array_is_zeroed(const void *arr, unsigned int arr_len, size_t arr_stride); +bool _bli_array_is_zeroed(const void *arr, uint arr_len, size_t arr_stride); #define BLI_array_is_zeroed(arr, arr_len) _bli_array_is_zeroed(arr, arr_len, sizeof(*(arr))) bool _bli_array_iter_spiral_square(const void *arr_v, diff --git a/source/blender/blenlib/BLI_assert.h b/source/blender/blenlib/BLI_assert.h index 685f526b4ad..7f7bec425ce 100644 --- a/source/blender/blenlib/BLI_assert.h +++ b/source/blender/blenlib/BLI_assert.h @@ -31,6 +31,7 @@ extern "C" { /* Utility functions. */ void _BLI_assert_print_pos(const char *file, const int line, const char *function, const char *id); +void _BLI_assert_print_extra(const char *str); void _BLI_assert_print_backtrace(void); void _BLI_assert_abort(void); void _BLI_assert_unreachable_print(const char *file, const int line, const char *function); @@ -61,8 +62,17 @@ void _BLI_assert_unreachable_print(const char *file, const int line, const char _BLI_ASSERT_ABORT(), \ NULL)) : \ NULL) +/** A version of #BLI_assert() to pass an additional message to be printed on failure. */ +# define BLI_assert_msg(a, msg) \ + (void)((!(a)) ? ((_BLI_assert_print_backtrace(), \ + _BLI_ASSERT_PRINT_POS(a), \ + _BLI_assert_print_extra(msg), \ + _BLI_ASSERT_ABORT(), \ + NULL)) : \ + NULL) #else # define BLI_assert(a) ((void)0) +# define BLI_assert_msg(a, msg) ((void)0) #endif #if defined(__cplusplus) diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh index 25fd02b41fb..3051d980d45 100644 --- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh +++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh @@ -77,17 +77,18 @@ template<typename T> class EnumerableThreadSpecific : NonCopyable, NonMovable { * their addresses do not change when the map grows. */ Map<int, std::reference_wrapper<T>> values_; Vector<std::unique_ptr<T>> owned_values_; - std::function<T()> initializer_; + std::function<void(void *)> initializer_; public: using iterator = typename Map<int, std::reference_wrapper<T>>::MutableValueIterator; - EnumerableThreadSpecific() : initializer_([]() { return T(); }) + EnumerableThreadSpecific() : initializer_([](void *buffer) { new (buffer) T(); }) { } template<typename F> - EnumerableThreadSpecific(F initializer) : initializer_(std::move(initializer)) + EnumerableThreadSpecific(F initializer) + : initializer_([=](void *buffer) { new (buffer) T(initializer()); }) { } @@ -96,11 +97,10 @@ template<typename T> class EnumerableThreadSpecific : NonCopyable, NonMovable { const int thread_id = enumerable_thread_specific_utils::thread_id; std::lock_guard lock{mutex_}; return values_.lookup_or_add_cb(thread_id, [&]() { - /* `std::make_unique` does not work here if T is non-copyable and non-movable. */ - std::unique_ptr<T> value{new T(initializer_())}; - std::reference_wrapper<T> ref = *value; - owned_values_.append(std::move(value)); - return ref; + T *value = (T *)::operator new(sizeof(T)); + initializer_(value); + owned_values_.append(std::unique_ptr<T>{value}); + return std::reference_wrapper<T>{*value}; }); } diff --git a/source/blender/blenlib/BLI_function_ref.hh b/source/blender/blenlib/BLI_function_ref.hh index 38e1ba593c5..70a064adc5d 100644 --- a/source/blender/blenlib/BLI_function_ref.hh +++ b/source/blender/blenlib/BLI_function_ref.hh @@ -95,7 +95,7 @@ template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> { * A pointer to the referenced callable object. This can be a C function, a lambda object or any * other callable. * - * The value does not need to be initialized because it is not used unless callback_ is set as + * The value does not need to be initialized because it is not used unless `callback_` is set as * well, in which case it will be initialized as well. * * Use `intptr_t` to avoid warnings when casting to function pointers. diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh b/source/blender/blenlib/BLI_mesh_intersect.hh index a19682327a5..f28be9bf59b 100644 --- a/source/blender/blenlib/BLI_mesh_intersect.hh +++ b/source/blender/blenlib/BLI_mesh_intersect.hh @@ -225,6 +225,7 @@ class IMeshArena : NonCopyable, NonMovable { */ const Vert *add_or_find_vert(const mpq3 &co, int orig); const Vert *add_or_find_vert(const double3 &co, int orig); + const Vert *add_or_find_vert(Vert *vert); Face *add_face(Span<const Vert *> verts, int orig, diff --git a/source/blender/blenlib/BLI_set_slots.hh b/source/blender/blenlib/BLI_set_slots.hh index a4d01dfdb68..d50ef95f11e 100644 --- a/source/blender/blenlib/BLI_set_slots.hh +++ b/source/blender/blenlib/BLI_set_slots.hh @@ -249,7 +249,7 @@ template<typename Key> class HashedSetSlot { template<typename ForwardKey, typename IsEqual> bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const { - /* hash_ might be uninitialized here, but that is ok. */ + /* `hash_` might be uninitialized here, but that is ok. */ if (hash_ == hash) { if (state_ == Occupied) { return is_equal(key, *key_buffer_); diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh index 5f5a17f6b58..e2446ad143e 100644 --- a/source/blender/blenlib/BLI_task.hh +++ b/source/blender/blenlib/BLI_task.hh @@ -28,6 +28,7 @@ # define NOMINMAX # define TBB_MIN_MAX_CLEANUP # endif +# include "tbb/parallel_reduce.h" # include <tbb/blocked_range.h> # include <tbb/parallel_for.h> # include <tbb/parallel_for_each.h> @@ -76,6 +77,27 @@ void parallel_for(IndexRange range, int64_t grain_size, const Function &function #endif } +template<typename Value, typename Function, typename Reduction> +Value parallel_reduce(IndexRange range, + int64_t grain_size, + const Value &identity, + const Function &function, + const Reduction &reduction) +{ +#ifdef WITH_TBB + return tbb::parallel_reduce( + tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size), + identity, + [&](const tbb::blocked_range<int64_t> &subrange, const Value &ident) { + return function(IndexRange(subrange.begin(), subrange.size()), ident); + }, + reduction); +#else + UNUSED_VARS(grain_size, reduction); + return function(range, identity); +#endif +} + /** See #BLI_task_isolate for a description of what isolating a task means. */ template<typename Function> void isolate_task(const Function &function) { diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 677df9db026..ea5572f1c8a 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -188,6 +188,7 @@ set(SRC BLI_dynstr.h BLI_easing.h BLI_edgehash.h + BLI_endian_defines.h BLI_endian_switch.h BLI_endian_switch_inline.h BLI_enumerable_thread_specific.hh diff --git a/source/blender/blenlib/intern/BLI_assert.c b/source/blender/blenlib/intern/BLI_assert.c index 887f583242f..cebc6f8957f 100644 --- a/source/blender/blenlib/intern/BLI_assert.c +++ b/source/blender/blenlib/intern/BLI_assert.c @@ -31,6 +31,11 @@ void _BLI_assert_print_pos(const char *file, const int line, const char *functio fprintf(stderr, "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", file, line, function, id); } +void _BLI_assert_print_extra(const char *str) +{ + fprintf(stderr, " %s\n", str); +} + void _BLI_assert_unreachable_print(const char *file, const int line, const char *function) { fprintf(stderr, "Code marked as unreachable has been executed. Please report this as a bug.\n"); diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index 79f96fc4c71..f05dea46dc8 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -462,7 +462,7 @@ void BLI_filelist_entry_free(struct direntry *entry) } /** - * frees storage for an array of direntries, including the array itself. + * Frees storage for an array of #direntry, including the array itself. */ void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries) { diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c index 25261e82cc9..9a12a7442b7 100644 --- a/source/blender/blenlib/intern/array_utils.c +++ b/source/blender/blenlib/intern/array_utils.c @@ -40,11 +40,11 @@ * * Access via #BLI_array_reverse */ -void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride) +void _bli_array_reverse(void *arr_v, uint arr_len, size_t arr_stride) { - const unsigned int arr_stride_uint = (unsigned int)arr_stride; - const unsigned int arr_half_stride = (arr_len / 2) * arr_stride_uint; - unsigned int i, i_end; + const uint arr_stride_uint = (uint)arr_stride; + const uint arr_half_stride = (arr_len / 2) * arr_stride_uint; + uint i, i_end; char *arr = arr_v; char *buf = BLI_array_alloca(buf, arr_stride); @@ -62,7 +62,7 @@ void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride) * * Access via #BLI_array_wrap */ -void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir) +void _bli_array_wrap(void *arr_v, uint arr_len, size_t arr_stride, int dir) { char *arr = arr_v; char *buf = BLI_array_alloca(buf, arr_stride); @@ -88,16 +88,13 @@ void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int d * * Access via #BLI_array_wrap */ -void _bli_array_permute(void *arr, - const unsigned int arr_len, - const size_t arr_stride, - const unsigned int *order, - void *arr_temp) +void _bli_array_permute( + void *arr, const uint arr_len, const size_t arr_stride, const uint *order, void *arr_temp) { const size_t len = arr_len * arr_stride; - const unsigned int arr_stride_uint = (unsigned int)arr_stride; + const uint arr_stride_uint = (uint)arr_stride; void *arr_orig; - unsigned int i; + uint i; if (arr_temp == NULL) { arr_orig = MEM_mallocN(len, __func__); @@ -121,16 +118,45 @@ void _bli_array_permute(void *arr, } /** + * In-place array de-duplication of an ordered array. + * + * \return The new length of the array. + * + * Access via #BLI_array_deduplicate_ordered + */ +uint _bli_array_deduplicate_ordered(void *arr, uint arr_len, size_t arr_stride) +{ + if (UNLIKELY(arr_len <= 1)) { + return arr_len; + } + + const uint arr_stride_uint = (uint)arr_stride; + uint j = 0; + for (uint i = 0; i < arr_len; i++) { + if ((i == j) || (memcmp(POINTER_OFFSET(arr, arr_stride_uint * i), + POINTER_OFFSET(arr, arr_stride_uint * j), + arr_stride) == 0)) { + continue; + } + j += 1; + memcpy(POINTER_OFFSET(arr, arr_stride_uint * j), + POINTER_OFFSET(arr, arr_stride_uint * i), + arr_stride); + } + return j + 1; +} + +/** * Find the first index of an item in an array. * * Access via #BLI_array_findindex * * \note Not efficient, use for error checks/asserts. */ -int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p) +int _bli_array_findindex(const void *arr, uint arr_len, size_t arr_stride, const void *p) { const char *arr_step = (const char *)arr; - for (unsigned int i = 0; i < arr_len; i++, arr_step += arr_stride) { + for (uint i = 0; i < arr_len; i++, arr_step += arr_stride) { if (memcmp(arr_step, p, arr_stride) == 0) { return (int)i; } @@ -141,10 +167,10 @@ int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_strid /** * A version of #BLI_array_findindex that searches from the end of the list. */ -int _bli_array_rfindindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p) +int _bli_array_rfindindex(const void *arr, uint arr_len, size_t arr_stride, const void *p) { const char *arr_step = (const char *)arr + (arr_stride * arr_len); - for (unsigned int i = arr_len; i-- != 0;) { + for (uint i = arr_len; i-- != 0;) { arr_step -= arr_stride; if (memcmp(arr_step, p, arr_stride) == 0) { return (int)i; @@ -154,7 +180,7 @@ int _bli_array_rfindindex(const void *arr, unsigned int arr_len, size_t arr_stri } void _bli_array_binary_and( - void *arr, const void *arr_a, const void *arr_b, unsigned int arr_len, size_t arr_stride) + void *arr, const void *arr_a, const void *arr_b, uint arr_len, size_t arr_stride) { char *dst = arr; const char *src_a = arr_a; @@ -167,7 +193,7 @@ void _bli_array_binary_and( } void _bli_array_binary_or( - void *arr, const void *arr_a, const void *arr_b, unsigned int arr_len, size_t arr_stride) + void *arr, const void *arr_a, const void *arr_b, uint arr_len, size_t arr_stride) { char *dst = arr; const char *src_a = arr_a; @@ -196,14 +222,14 @@ void _bli_array_binary_or( * where calculating the length isn't a simple subtraction. */ bool _bli_array_iter_span(const void *arr, - unsigned int arr_len, + uint arr_len, size_t arr_stride, bool use_wrap, bool use_delimit_bounds, bool (*test_fn)(const void *arr_item, void *user_data), void *user_data, - unsigned int span_step[2], - unsigned int *r_span_len) + uint span_step[2], + uint *r_span_len) { if (arr_len == 0) { return false; @@ -212,11 +238,11 @@ bool _bli_array_iter_span(const void *arr, return false; } - const unsigned int arr_stride_uint = (unsigned int)arr_stride; + const uint arr_stride_uint = (uint)arr_stride; const void *item_prev; bool test_prev; - unsigned int i_curr; + uint i_curr; if ((span_step[0] == arr_len) && (span_step[1] == arr_len)) { if (use_wrap) { @@ -249,11 +275,11 @@ bool _bli_array_iter_span(const void *arr, while (i_curr < arr_len) { bool test_curr = test_fn(item_curr, user_data); if ((test_prev == false) && (test_curr == true)) { - unsigned int span_len; - unsigned int i_step_prev = i_curr; + uint span_len; + uint i_step_prev = i_curr; if (use_wrap) { - unsigned int i_step = i_curr + 1; + uint i_step = i_curr + 1; if (UNLIKELY(i_step == arr_len)) { i_step = 0; } @@ -273,7 +299,7 @@ bool _bli_array_iter_span(const void *arr, } } else { - unsigned int i_step = i_curr + 1; + uint i_step = i_curr + 1; while ((i_step != arr_len) && test_fn(POINTER_OFFSET(arr, i_step * arr_stride_uint), user_data)) { i_step_prev = i_step; @@ -307,7 +333,7 @@ bool _bli_array_iter_span(const void *arr, /** * Simple utility to check memory is zeroed. */ -bool _bli_array_is_zeroed(const void *arr_v, unsigned int arr_len, size_t arr_stride) +bool _bli_array_is_zeroed(const void *arr_v, uint arr_len, size_t arr_stride) { const char *arr_step = (const char *)arr_v; size_t i = arr_stride * arr_len; diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index db2b7c055a5..34baac6f2a4 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -167,7 +167,7 @@ void invert_qt_qt_normalized(float q1[4], const float q2[4]) invert_qt_normalized(q1); } -/* simple mult */ +/* Simple multiply. */ void mul_qt_fl(float q[4], const float f) { q[0] *= f; @@ -373,7 +373,7 @@ void mat3_normalized_to_quat(float q[4], const float mat[3][3]) q[2] = (mat[2][1] + mat[1][2]) * s; } - /* Make sure w is nonnegative for a canonical result. */ + /* Make sure W is non-negative for a canonical result. */ if (q[0] < 0) { negate_v4(q); } diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index 9f7824a0029..8b8850c7cdb 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -21,6 +21,7 @@ #ifdef WITH_GMP # include <algorithm> +# include <atomic> # include <fstream> # include <iostream> @@ -50,6 +51,7 @@ # include "BLI_mesh_boolean.hh" # ifdef WITH_TBB +# include "tbb/parallel_reduce.h" # include "tbb/spin_mutex.h" # endif @@ -201,9 +203,14 @@ TriMeshTopology::TriMeshTopology(const IMesh &tm) BLI_assert(edges != nullptr); } edges->append_non_duplicates(e); - auto createf = [t](Vector<int> **pvec) { *pvec = new Vector<int>{t}; }; - auto modifyf = [t](Vector<int> **pvec) { (*pvec)->append_non_duplicates(t); }; - this->edge_tri_.add_or_modify(Edge(v, vnext), createf, modifyf); + + auto p = edge_tri_.lookup_ptr(Edge(v, vnext)); + if (p == nullptr) { + edge_tri_.add_new(e, new Vector<int>{t}); + } + else { + (*p)->append_non_duplicates(t); + } } } /* Debugging. */ @@ -228,9 +235,18 @@ TriMeshTopology::TriMeshTopology(const IMesh &tm) TriMeshTopology::~TriMeshTopology() { - for (const Vector<int> *vec : edge_tri_.values()) { - delete vec; + Vector<Vector<int> *> values; + + /* Deconstructing is faster in parallel, so it is worth building an array of things to delete. */ + for (auto item : edge_tri_.values()) { + values.append(item); } + + threading::parallel_for(values.index_range(), 256, [&](IndexRange range) { + for (int i : range) { + delete values[i]; + } + }); } /** A Patch is a maximal set of triangles that share manifold edges only. */ @@ -719,6 +735,18 @@ static PatchesInfo find_patches(const IMesh &tm, const TriMeshTopology &tmtopo) PatchesInfo pinfo(ntri); /* Algorithm: Grow patches across manifold edges as long as there are unassigned triangles. */ Stack<int> cur_patch_grow; + + /* Create an Array containing indices of adjacent faces. */ + Array<std::array<int, 3>> t_others(tm.face_size()); + threading::parallel_for(tm.face_index_range(), 2048, [&](IndexRange range) { + for (int t : range) { + const Face &tri = *tm.face(t); + for (int i = 0; i < 3; ++i) { + Edge e(tri[i], tri[(i + 1) % 3]); + t_others[t][i] = tmtopo.other_tri_if_manifold(e, t); + } + } + }); for (int t : tm.face_index_range()) { if (pinfo.tri_patch(t) == -1) { cur_patch_grow.push(t); @@ -739,7 +767,7 @@ static PatchesInfo find_patches(const IMesh &tm, const TriMeshTopology &tmtopo) const Face &tri = *tm.face(tcand); for (int i = 0; i < 3; ++i) { Edge e(tri[i], tri[(i + 1) % 3]); - int t_other = tmtopo.other_tri_if_manifold(e, tcand); + int t_other = t_others[tcand][i]; if (dbg_level > 1) { std::cout << " edge " << e << " generates t_other=" << t_other << "\n"; } @@ -953,12 +981,8 @@ static void sort_by_signed_triangle_index(Vector<int> &g, * To accommodate this: * If extra_tri is non-null, then an index of EXTRA_TRI_INDEX should use it for the triangle. */ -static Array<int> sort_tris_around_edge(const IMesh &tm, - const TriMeshTopology &tmtopo, - const Edge e, - const Span<int> tris, - const int t0, - const Face *extra_tri) +static Array<int> sort_tris_around_edge( + const IMesh &tm, const Edge e, const Span<int> tris, const int t0, const Face *extra_tri) { /* Divide and conquer, quick-sort-like sort. * Pick a triangle t0, then partition into groups: @@ -1023,14 +1047,14 @@ static Array<int> sort_tris_around_edge(const IMesh &tm, } } if (g3.size() > 1) { - Array<int> g3sorted = sort_tris_around_edge(tm, tmtopo, e, g3, t0, extra_tri); + Array<int> g3sorted = sort_tris_around_edge(tm, e, g3, t0, extra_tri); std::copy(g3sorted.begin(), g3sorted.end(), g3.begin()); if (dbg_level > 1) { std::cout << "g3 sorted: " << g3 << "\n"; } } if (g4.size() > 1) { - Array<int> g4sorted = sort_tris_around_edge(tm, tmtopo, e, g4, t0, extra_tri); + Array<int> g4sorted = sort_tris_around_edge(tm, e, g4, t0, extra_tri); std::copy(g4sorted.begin(), g4sorted.end(), g4.begin()); if (dbg_level > 1) { std::cout << "g4 sorted: " << g4 << "\n"; @@ -1076,7 +1100,7 @@ static void find_cells_from_edge(const IMesh &tm, const Vector<int> *edge_tris = tmtopo.edge_tris(e); BLI_assert(edge_tris != nullptr); Array<int> sorted_tris = sort_tris_around_edge( - tm, tmtopo, e, Span<int>(*edge_tris), (*edge_tris)[0], nullptr); + tm, e, Span<int>(*edge_tris), (*edge_tris)[0], nullptr); int n_edge_tris = edge_tris->size(); Array<int> edge_patches(n_edge_tris); @@ -1338,34 +1362,46 @@ static bool patch_cell_graph_ok(const CellsInfo &cinfo, const PatchesInfo &pinfo static bool is_pwn(const IMesh &tm, const TriMeshTopology &tmtopo) { constexpr int dbg_level = 0; + std::atomic<bool> is_pwn = true; + Vector<std::pair<Edge, Vector<int> *>> tris; + for (auto item : tmtopo.edge_tri_map_items()) { - const Edge &edge = item.key; - int tot_orient = 0; - /* For each face t attached to edge, add +1 if the edge - * is positively in t, and -1 if negatively in t. */ - for (int t : *item.value) { - const Face &face = *tm.face(t); - BLI_assert(face.size() == 3); - for (int i : face.index_range()) { - if (face[i] == edge.v0()) { - if (face[(i + 1) % 3] == edge.v1()) { - ++tot_orient; - } - else { - BLI_assert(face[(i + 3 - 1) % 3] == edge.v1()); - --tot_orient; + tris.append(std::pair<Edge, Vector<int> *>(item.key, item.value)); + } + + threading::parallel_for(tris.index_range(), 2048, [&](IndexRange range) { + for (int j : range) { + const Edge &edge = tris[j].first; + int tot_orient = 0; + /* For each face t attached to edge, add +1 if the edge + * is positively in t, and -1 if negatively in t. */ + for (int t : *tris[j].second) { + const Face &face = *tm.face(t); + BLI_assert(face.size() == 3); + for (int i : face.index_range()) { + if (face[i] == edge.v0()) { + if (face[(i + 1) % 3] == edge.v1()) { + ++tot_orient; + } + else { + BLI_assert(face[(i + 3 - 1) % 3] == edge.v1()); + --tot_orient; + } } } } - } - if (tot_orient != 0) { - if (dbg_level > 0) { - std::cout << "edge causing non-pwn: " << edge << "\n"; + if (tot_orient != 0) { + if (dbg_level > 0) { + std::cout << "edge causing non-pwn: " << edge << "\n"; + } + is_pwn = false; +# ifdef WITH_TBB + tbb::task::self().cancel_group_execution(); +# endif } - return false; } - } - return true; + }); + return is_pwn.load(); } /** @@ -1396,8 +1432,7 @@ static int find_cell_for_point_near_edge(mpq3 p, Array<int> edge_tris(etris->size() + 1); std::copy(etris->begin(), etris->end(), edge_tris.begin()); edge_tris[edge_tris.size() - 1] = EXTRA_TRI_INDEX; - Array<int> sorted_tris = sort_tris_around_edge( - tm, tmtopo, e, edge_tris, edge_tris[0], dummy_tri); + Array<int> sorted_tris = sort_tris_around_edge(tm, e, edge_tris, edge_tris[0], dummy_tri); if (dbg_level > 0) { std::cout << "sorted tris = " << sorted_tris << "\n"; } @@ -1452,39 +1487,66 @@ static int find_ambient_cell(const IMesh &tm, /* First find a vertex with the maximum x value. */ /* Prefer not to populate the verts in the #IMesh just for this. */ const Vert *v_extreme; - mpq_class extreme_x; + auto max_x_vert = [](const Vert *a, const Vert *b) { + return (a->co_exact.x > b->co_exact.x) ? a : b; + }; if (component_patches == nullptr) { - v_extreme = (*tm.face(0))[0]; - extreme_x = v_extreme->co_exact.x; - for (const Face *f : tm.faces()) { - for (const Vert *v : *f) { - const mpq_class &x = v->co_exact.x; - if (x > extreme_x) { - v_extreme = v; - extreme_x = x; - } - } - } + v_extreme = threading::parallel_reduce( + tm.face_index_range(), + 2048, + (*tm.face(0))[0], + [&](IndexRange range, const Vert *init) { + const Vert *ans = init; + for (int i : range) { + const Face *f = tm.face(i); + for (const Vert *v : *f) { + if (v->co_exact.x > ans->co_exact.x) { + ans = v; + } + } + } + return ans; + }, + max_x_vert); } else { if (dbg_level > 0) { std::cout << "restrict to patches " << *component_patches << "\n"; } int p0 = (*component_patches)[0]; - v_extreme = (*tm.face(pinfo.patch(p0).tri(0)))[0]; - extreme_x = v_extreme->co_exact.x; - for (int p : *component_patches) { - for (int t : pinfo.patch(p).tris()) { - const Face *f = tm.face(t); - for (const Vert *v : *f) { - const mpq_class &x = v->co_exact.x; - if (x > extreme_x) { - v_extreme = v; - extreme_x = x; + v_extreme = threading::parallel_reduce( + component_patches->index_range(), + 2048, + (*tm.face(pinfo.patch(p0).tri(0)))[0], + [&](IndexRange range, const Vert *init) { + const Vert *ans = init; + for (int pi : range) { + int p = (*component_patches)[pi]; + const Vert *tris_ans = threading::parallel_reduce( + IndexRange(pinfo.patch(p).tot_tri()), + 2048, + init, + [&](IndexRange tris_range, const Vert *t_init) { + const Vert *v_ans = t_init; + for (int i : tris_range) { + int t = pinfo.patch(p).tri(i); + const Face *f = tm.face(t); + for (const Vert *v : *f) { + if (v->co_exact.x > v_ans->co_exact.x) { + v_ans = v; + } + } + } + return v_ans; + }, + max_x_vert); + if (tris_ans->co_exact.x > ans->co_exact.x) { + ans = tris_ans; + } } - } - } - } + return ans; + }, + max_x_vert); } if (dbg_level > 0) { std::cout << "v_extreme = " << v_extreme << "\n"; @@ -1493,7 +1555,8 @@ static int find_ambient_cell(const IMesh &tm, * when projected onto the XY plane. That edge is guaranteed to * be on the convex hull of the mesh. */ const Vector<Edge> &edges = tmtopo.vert_edges(v_extreme); - const mpq_class extreme_y = v_extreme->co_exact.y; + const mpq_class &extreme_x = v_extreme->co_exact.x; + const mpq_class &extreme_y = v_extreme->co_exact.y; Edge ehull; mpq_class max_abs_slope = -1; for (Edge e : edges) { @@ -1514,8 +1577,8 @@ static int find_ambient_cell(const IMesh &tm, if (dbg_level > 0) { std::cout << "ehull = " << ehull << " slope = " << max_abs_slope << "\n"; } - /* Sort triangles around ehull, including a dummy triangle that include a known point in ambient - * cell. */ + /* Sort triangles around ehull, including a dummy triangle that include a known point in + * ambient cell. */ mpq3 p_in_ambient = v_extreme->co_exact; p_in_ambient.x += 1; int c_ambient = find_cell_for_point_near_edge(p_in_ambient, ehull, tm, tmtopo, pinfo, arena); @@ -2816,7 +2879,8 @@ static IMesh raycast_patches_boolean(const IMesh &tm, } /** * If \a tri1 and \a tri2 have a common edge (in opposite orientation), - * return the indices into \a tri1 and \a tri2 where that common edge starts. Else return (-1,-1). + * return the indices into \a tri1 and \a tri2 where that common edge starts. Else return + * (-1,-1). */ static std::pair<int, int> find_tris_common_edge(const Face &tri1, const Face &tri2) { @@ -3378,8 +3442,8 @@ static void dissolve_verts(IMesh *imesh, const Array<bool> dissolve, IMeshArena * will have an original edge that is NO_INDEX. * Not all triangulation edges can be removed: if they ended up non-trivially overlapping a real * input edge, then we need to keep it. Also, some are necessary to make the output satisfy - * the "valid #BMesh" property: we can't produce output faces that have repeated vertices in them, - * or have several disconnected boundaries (e.g., faces with holes). + * the "valid #BMesh" property: we can't produce output faces that have repeated vertices in + * them, or have several disconnected boundaries (e.g., faces with holes). */ static IMesh polymesh_from_trimesh_with_dissolve(const IMesh &tm_out, const IMesh &imesh_in, diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index c8028231e81..f91dd762e70 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -43,6 +43,7 @@ # include "BLI_set.hh" # include "BLI_span.hh" # include "BLI_task.h" +# include "BLI_task.hh" # include "BLI_threads.h" # include "BLI_vector.hh" # include "BLI_vector_set.hh" @@ -51,6 +52,10 @@ # include "BLI_mesh_intersect.hh" +# ifdef WITH_TBB +# include "tbb/parallel_sort.h" +# endif + // # define PERFDEBUG namespace blender::meshintersect { @@ -406,6 +411,11 @@ class IMeshArena::IMeshArenaImpl : NonCopyable, NonMovable { return add_or_find_vert(mco, co, orig); } + const Vert *add_or_find_vert(Vert *vert) + { + return add_or_find_vert_(vert); + } + Face *add_face(Span<const Vert *> verts, int orig, Span<int> edge_origs, Span<bool> is_intersect) { Face *f = new Face(verts, next_face_id_++, orig, edge_origs, is_intersect); @@ -486,10 +496,48 @@ class IMeshArena::IMeshArenaImpl : NonCopyable, NonMovable { private: const Vert *add_or_find_vert(const mpq3 &mco, const double3 &dco, int orig) { - /* Don't allocate Vert yet, in case it is already there. */ - Vert vtry(mco, dco, NO_INDEX, NO_INDEX); + Vert *vtry = new Vert(mco, dco, NO_INDEX, NO_INDEX); const Vert *ans; - VSetKey vskey(&vtry); + VSetKey vskey(vtry); + if (intersect_use_threading) { +# ifdef USE_SPINLOCK + BLI_spin_lock(&lock_); +# else + BLI_mutex_lock(mutex_); +# endif + } + const VSetKey *lookup = vset_.lookup_key_ptr(vskey); + if (!lookup) { + vtry->id = next_vert_id_++; + vtry->orig = orig; + vskey.vert = vtry; // new Vert(mco, dco, next_vert_id_++, orig); + vset_.add_new(vskey); + allocated_verts_.append(std::unique_ptr<Vert>(vskey.vert)); + ans = vskey.vert; + } + else { + /* It was a duplicate, so return the existing one. + * Note that the returned Vert may have a different orig. + * This is the intended semantics: if the Vert already + * exists then we are merging verts and using the first-seen + * one as the canonical one. */ + delete vtry; + ans = lookup->vert; + } + if (intersect_use_threading) { +# ifdef USE_SPINLOCK + BLI_spin_unlock(&lock_); +# else + BLI_mutex_unlock(mutex_); +# endif + } + return ans; + }; + + const Vert *add_or_find_vert_(Vert *vtry) + { + const Vert *ans; + VSetKey vskey(vtry); if (intersect_use_threading) { # ifdef USE_SPINLOCK BLI_spin_lock(&lock_); @@ -499,7 +547,8 @@ class IMeshArena::IMeshArenaImpl : NonCopyable, NonMovable { } const VSetKey *lookup = vset_.lookup_key_ptr(vskey); if (!lookup) { - vskey.vert = new Vert(mco, dco, next_vert_id_++, orig); + vtry->id = next_vert_id_++; + vskey.vert = vtry; // new Vert(mco, dco, next_vert_id_++, orig); vset_.add_new(vskey); allocated_verts_.append(std::unique_ptr<Vert>(vskey.vert)); ans = vskey.vert; @@ -510,6 +559,7 @@ class IMeshArena::IMeshArenaImpl : NonCopyable, NonMovable { * This is the intended semantics: if the Vert already * exists then we are merging verts and using the first-seen * one as the canonical one. */ + delete vtry; ans = lookup->vert; } if (intersect_use_threading) { @@ -550,6 +600,11 @@ const Vert *IMeshArena::add_or_find_vert(const mpq3 &co, int orig) return pimpl_->add_or_find_vert(co, orig); } +const Vert *IMeshArena::add_or_find_vert(Vert *vert) +{ + return pimpl_->add_or_find_vert(vert); +} + Face *IMeshArena::add_face(Span<const Vert *> verts, int orig, Span<int> edge_origs, @@ -633,7 +688,11 @@ void IMesh::populate_vert(int max_verts) * TODO: when all debugged, set fix_order = false. */ const bool fix_order = true; if (fix_order) { +# ifdef WITH_TBB + tbb::parallel_sort(vert_.begin(), vert_.end(), [](const Vert *a, const Vert *b) { +# else std::sort(vert_.begin(), vert_.end(), [](const Vert *a, const Vert *b) { +# endif if (a->orig != NO_INDEX && b->orig != NO_INDEX) { return a->orig < b->orig; } @@ -2187,6 +2246,14 @@ IMesh triangulate_polymesh(IMesh &imesh, IMeshArena *arena) Vector<Face *> face_tris; constexpr int estimated_tris_per_face = 3; face_tris.reserve(estimated_tris_per_face * imesh.face_size()); + threading::parallel_for(imesh.face_index_range(), 2048, [&](IndexRange range) { + for (int i : range) { + Face *f = imesh.face(i); + if (!f->plane_populated() && f->size() >= 4) { + f->populate_plane(false); + } + } + }); for (Face *f : imesh.faces()) { /* Tessellate face f, following plan similar to #BM_face_calc_tessellation. */ int flen = f->size(); @@ -2278,12 +2345,22 @@ class TriOverlaps { if (two_trees_no_self) { tree_b_ = BLI_bvhtree_new(tm.face_size(), FLT_EPSILON, 8, 6); } + + /* Create a Vector containing face shape. */ + Vector<int> shapes; + shapes.resize(tm.face_size()); + threading::parallel_for(tm.face_index_range(), 2048, [&](IndexRange range) { + for (int t : range) { + shapes[t] = shape_fn(tm.face(t)->orig); + } + }); + float bbpts[6]; for (int t : tm.face_index_range()) { const BoundingBox &bb = tri_bb[t]; copy_v3_v3(bbpts, bb.min); copy_v3_v3(bbpts + 3, bb.max); - int shape = shape_fn(tm.face(t)->orig); + int shape = shapes[t]; if (two_trees_no_self) { if (shape == 0) { BLI_bvhtree_insert(tree_, t, bbpts, 2); @@ -2575,11 +2652,13 @@ static void calc_subdivided_non_cluster_tris(Array<IMesh> &r_tri_subdivided, 0, overlap_tri_range_tot, &data, calc_subdivided_tri_range_func, &settings); /* Now have to put in the triangles that are the same as the input ones, and not in clusters. */ - for (int t : tm.face_index_range()) { - if (r_tri_subdivided[t].face_size() == 0 && clinfo.tri_cluster(t) == NO_INDEX) { - r_tri_subdivided[t] = IMesh({tm.face(t)}); + threading::parallel_for(tm.face_index_range(), 2048, [&](IndexRange range) { + for (int t : range) { + if (r_tri_subdivided[t].face_size() == 0 && clinfo.tri_cluster(t) == NO_INDEX) { + r_tri_subdivided[t] = IMesh({tm.face(t)}); + } } - } + }); } /** @@ -2936,11 +3015,15 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in, double overlap_time = PIL_check_seconds_timer(); std::cout << "intersect overlaps calculated, time = " << overlap_time - bb_calc_time << "\n"; # endif - for (int t : tm_clean->face_index_range()) { - if (tri_ov.first_overlap_index(t) != -1) { - tm_clean->face(t)->populate_plane(true); + Array<IMesh> tri_subdivided(tm_clean->face_size(), NoInitialization()); + threading::parallel_for(tm_clean->face_index_range(), 1024, [&](IndexRange range) { + for (int t : range) { + if (tri_ov.first_overlap_index(t) != -1) { + tm_clean->face(t)->populate_plane(true); + } + new (static_cast<void *>(&tri_subdivided[t])) IMesh; } - } + }); # ifdef PERFDEBUG double plane_populate = PIL_check_seconds_timer(); std::cout << "planes populated, time = " << plane_populate - overlap_time << "\n"; @@ -2965,7 +3048,6 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in, doperfmax(1, clinfo.tot_cluster()); doperfmax(2, tri_ov.overlap().size()); # endif - Array<IMesh> tri_subdivided(tm_clean->face_size()); calc_subdivided_non_cluster_tris(tri_subdivided, *tm_clean, itt_map, clinfo, tri_ov, arena); # ifdef PERFDEBUG double subdivided_tris_time = PIL_check_seconds_timer(); diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index f9f5411d673..4d0dc43ed1e 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -235,13 +235,13 @@ void BLI_path_normalize(const char *relabase, char *path) memmove(path + a, eind, strlen(eind) + 1); } else { - /* support for odd paths: eg /../home/me --> /home/me + /* Support for odd paths: eg `/../home/me` --> `/home/me` * this is a valid path in blender but we can't handle this the usual way below * simply strip this prefix then evaluate the path as usual. - * pythons os.path.normpath() does this */ + * Python's `os.path.normpath()` does this. */ /* NOTE: previous version of following call used an offset of 3 instead of 4, - * which meant that the "/../home/me" example actually became "home/me". + * which meant that the `/../home/me` example actually became `home/me`. * Using offset of 3 gives behavior consistent with the aforementioned * Python routine. */ memmove(path, path + 3, strlen(path + 3) + 1); @@ -1070,8 +1070,8 @@ bool BLI_path_abs(char *path, const char *basepath) * paths relative to the .blend file -elubie */ BLI_str_replace_char(tmp + BLI_path_unc_prefix_len(tmp), '\\', '/'); - /* Paths starting with // will get the blend file as their base, - * this isn't standard in any os but is used in blender all over the place */ + /* Paths starting with `//` will get the blend file as their base, + * this isn't standard in any OS but is used in blender all over the place. */ if (wasrelative) { const char *lslash; BLI_strncpy(base, basepath, sizeof(base)); @@ -1275,7 +1275,7 @@ void BLI_setenv(const char *env, const char *val) { /* free windows */ -#if (defined(WIN32) || defined(WIN64)) +#if (defined(_WIN32) || defined(_WIN64)) uputenv(env, val); #else diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c index f4110c65a6d..87330cf4899 100644 --- a/source/blender/blenlib/intern/system.c +++ b/source/blender/blenlib/intern/system.c @@ -100,8 +100,8 @@ void BLI_system_backtrace(FILE *fp) # undef SIZE # else - /* ------------------ */ - /* non msvc/osx/linux */ + /* --------------------- */ + /* Non MSVC/Apple/Linux. */ (void)fp; # endif } diff --git a/source/blender/blenlib/tests/BLI_array_utils_test.cc b/source/blender/blenlib/tests/BLI_array_utils_test.cc index 5d12b8fbd4d..1bf221c5335 100644 --- a/source/blender/blenlib/tests/BLI_array_utils_test.cc +++ b/source/blender/blenlib/tests/BLI_array_utils_test.cc @@ -189,3 +189,53 @@ TEST(array_utils, BinaryOrInt4Mix) BINARY_OR_TEST(data_cmp, data_a, data_b, data_combine, ARRAY_SIZE(data_cmp)); } #undef BINARY_OR_TEST + +/* BLI_array_deduplicate_ordered */ +#define DEDUPLICATE_ORDERED_TEST(data, data_cmp) \ + { \ + const uint data_len_new = BLI_array_deduplicate_ordered(data, ARRAY_SIZE(data)); \ + EXPECT_EQ(data_len_new, ARRAY_SIZE(data_cmp)); \ + EXPECT_EQ_ARRAY(data, data_cmp, data_len_new); \ + /* Ensure running a second time does nothing. */ \ + const uint data_len_test = BLI_array_deduplicate_ordered(data, data_len_new); \ + EXPECT_EQ(data_len_test, ARRAY_SIZE(data_cmp)); \ + EXPECT_EQ_ARRAY(data, data_cmp, data_len_new); \ + } \ + ((void)0) + +TEST(array_utils, DeduplicateOrdered1) +{ + int data[] = {0}; + const int data_cmp[] = {0}; + DEDUPLICATE_ORDERED_TEST(data, data_cmp); +} + +TEST(array_utils, DeduplicateOrdered2) +{ + int data[] = {1, 2}; + const int data_cmp[] = {1, 2}; + DEDUPLICATE_ORDERED_TEST(data, data_cmp); +} + +TEST(array_utils, DeduplicateOrdered2Same) +{ + int data[] = {1, 1}; + const int data_cmp[] = {1}; + DEDUPLICATE_ORDERED_TEST(data, data_cmp); +} + +TEST(array_utils, DeduplicateOrdered3Same) +{ + int data[] = {1, 1, 1}; + const int data_cmp[] = {1}; + DEDUPLICATE_ORDERED_TEST(data, data_cmp); +} + +TEST(array_utils, DeduplicateOrdered3) +{ + int data[] = {3, 3, 2, 2, 1, 1}; + const int data_cmp[] = {3, 2, 1}; + DEDUPLICATE_ORDERED_TEST(data, data_cmp); +} + +#undef DEDUPLICATE_ORDERED_TEST diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 61a00ccdaa4..f5baf0dcb83 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -58,8 +58,8 @@ set(SRC intern/versioning_280.c intern/versioning_290.c intern/versioning_300.c - intern/versioning_cycles.c intern/versioning_common.cc + intern/versioning_cycles.c intern/versioning_defaults.c intern/versioning_dna.c intern/versioning_legacy.c diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 17f94e1e2b1..3c58c29c162 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -28,12 +28,15 @@ #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_brush_types.h" +#include "DNA_collection_types.h" #include "DNA_genfile.h" #include "DNA_listBase.h" #include "DNA_modifier_types.h" #include "DNA_text_types.h" +#include "BKE_action.h" #include "BKE_animsys.h" +#include "BKE_collection.h" #include "BKE_deform.h" #include "BKE_fcurve_driver.h" #include "BKE_lib_id.h" @@ -145,7 +148,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports)) assert_sorted_ids(bmain); } - if (!MAIN_VERSION_ATLEAST(bmain, 300, 8)) { + if (!MAIN_VERSION_ATLEAST(bmain, 300, 11)) { move_vertex_group_names_to_object_data(bmain); } @@ -486,6 +489,46 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 300, 8)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + if (scene->master_collection != NULL) { + BLI_strncpy(scene->master_collection->id.name + 2, + BKE_SCENE_COLLECTION_NAME, + sizeof(scene->master_collection->id.name) - 2); + } + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 300, 9)) { + /* Fix a bug where reordering FCurves and bActionGroups could cause some corruption. Just + * reconstruct all the action groups & ensure that the FCurves of a group are continuously + * stored (i.e. not mixed with other groups) to be sure. See T89435. */ + LISTBASE_FOREACH (bAction *, act, &bmain->actions) { + BKE_action_groups_reconstruct(act); + } + + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + if (ntree->type == NTREE_GEOMETRY) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + if (node->type == GEO_NODE_MESH_SUBDIVIDE) { + strcpy(node->idname, "GeometryNodeMeshSubdivide"); + } + } + } + } + FOREACH_NODETREE_END; + } + + if (!MAIN_VERSION_ATLEAST(bmain, 300, 10)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + ToolSettings *tool_settings = scene->toolsettings; + if (tool_settings->snap_uv_mode & (1 << 4)) { + tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */ + tool_settings->snap_uv_mode &= ~(1 << 4); + } + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 7aee93bb157..423d64ba62c 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -23,6 +23,8 @@ * that benefit from accessing connectivity information. */ +#include "BLI_assert.h" + /* disable holes for now, * these are ifdef'd because they use more memory and can't be saved in DNA currently */ // #define USE_BMESH_HOLES diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index ff6274cff12..bd28022de4b 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -221,21 +221,21 @@ void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], { BMOIter iter; BMElem *ele; - int count = BMO_slot_buffer_count(slot_args, slot_name); + const int slot_len = BMO_slot_buffer_len(slot_args, slot_name); BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array)); - if ((ele = BMO_iter_new(&iter, slot_args, slot_name, restrictmask)) && count > 0) { - BMElem **array = count > stack_array_size ? MEM_mallocN(sizeof(ele) * count, __func__) : - stack_array; + if ((ele = BMO_iter_new(&iter, slot_args, slot_name, restrictmask)) && slot_len > 0) { + BMElem **array = slot_len > stack_array_size ? MEM_mallocN(sizeof(ele) * slot_len, __func__) : + stack_array; int i = 0; do { array[i++] = ele; } while ((ele = BMO_iter_step(&iter))); - BLI_assert(i <= count); + BLI_assert(i <= slot_len); - if (i != count) { + if (i != slot_len) { if ((void **)array != stack_array) { array = MEM_reallocN(array, sizeof(ele) * i); } diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c b/source/blender/bmesh/intern/bmesh_mesh_normals.c index f429e77c656..f13b9a19533 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.c +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c @@ -19,7 +19,7 @@ * * BM mesh normal calculation functions. * - * \see mesh_normals.c for the equivalent #Mesh functionality. + * \see mesh_normals.cc for the equivalent #Mesh functionality. */ #include "MEM_guardedalloc.h" @@ -33,6 +33,7 @@ #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" @@ -525,7 +526,7 @@ bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr) } /** - * BMesh version of BKE_mesh_normals_loop_split() in mesh_evaluate.c + * BMesh version of BKE_mesh_normals_loop_split() in `mesh_evaluate.cc` * Will use first clnors_data array, and fallback to cd_loop_clnors_offset * (use NULL and -1 to not use clnors). * diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 9466be4a300..3978959a425 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -724,7 +724,7 @@ static BMOpDefine bmo_edgenet_fill_def = { }; /* - * Edgenet Prepare. + * Edge-net Prepare. * * Identifies several useful edge loop cases and modifies them so * they'll become a face when edgenet_fill is called. The cases covered are: diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 767c455e5e9..0f9488bd091 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -565,8 +565,8 @@ void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele); void *BMO_slot_buffer_get_single(BMOpSlot *slot); /* counts number of elements inside a slot array. */ -int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); -int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); +int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); +int BMO_slot_map_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, const void *element, const void *data); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 4a611d78d58..cf7697ad35f 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -678,7 +678,7 @@ void BMO_mesh_selected_remap(BMesh *bm, } } -int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name) +int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name) { BMOpSlot *slot = BMO_slot_get(slot_args, slot_name); BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); @@ -691,7 +691,7 @@ int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot return slot->len; } -int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name) +int BMO_slot_map_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name) { BMOpSlot *slot = BMO_slot_get(slot_args, slot_name); BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING); diff --git a/source/blender/bmesh/operators/bmo_beautify.c b/source/blender/bmesh/operators/bmo_beautify.c index de26ca5ebd2..a72ff6363ed 100644 --- a/source/blender/bmesh/operators/bmo_beautify.c +++ b/source/blender/bmesh/operators/bmo_beautify.c @@ -59,7 +59,7 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op) /* will over alloc if some edges can't be rotated */ edge_array = MEM_mallocN( - sizeof(*edge_array) * (size_t)BMO_slot_buffer_count(op->slots_in, "edges"), __func__); + sizeof(*edge_array) * (size_t)BMO_slot_buffer_len(op->slots_in, "edges"), __func__); BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { diff --git a/source/blender/bmesh/operators/bmo_bisect_plane.c b/source/blender/bmesh/operators/bmo_bisect_plane.c index 55b6337bea4..6296694f121 100644 --- a/source/blender/bmesh/operators/bmo_bisect_plane.c +++ b/source/blender/bmesh/operators/bmo_bisect_plane.c @@ -68,7 +68,7 @@ void bmo_bisect_plane_exec(BMesh *bm, BMOperator *op) /* Use an array of vertices because 'geom' contains both verts and edges that may use them. * Removing a vert may remove and edge which is later checked by #BMO_ITER. * over-allocate the total possible vert count. */ - const int vert_arr_max = min_ii(bm->totvert, BMO_slot_buffer_count(op->slots_in, "geom")); + const int vert_arr_max = min_ii(bm->totvert, BMO_slot_buffer_len(op->slots_in, "geom")); BMVert **vert_arr = MEM_mallocN(sizeof(*vert_arr) * (size_t)vert_arr_max, __func__); BMOIter siter; BMVert *v; diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index 2e2a7e0964e..a740e4d66e8 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -172,7 +172,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) BMO_op_exec(bm, &op_sub); /* return if edge net create did something */ - if (BMO_slot_buffer_count(op_sub.slots_out, "faces.out")) { + if (BMO_slot_buffer_len(op_sub.slots_out, "faces.out")) { BMO_slot_copy(&op_sub, slots_out, "faces.out", op, slots_out, "faces.out"); BMO_op_finish(bm, &op_sub); return; @@ -191,7 +191,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) BMO_op_exec(bm, &op_sub); /* if we dissolved anything, then return */ - if (BMO_slot_buffer_count(op_sub.slots_out, "region.out")) { + if (BMO_slot_buffer_len(op_sub.slots_out, "region.out")) { BMO_slot_copy(&op_sub, slots_out, "region.out", op, slots_out, "faces.out"); BMO_op_finish(bm, &op_sub); return; @@ -211,7 +211,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) BMO_op_exec(bm, &op_sub); /* return if edge loop fill did something */ - if (BMO_slot_buffer_count(op_sub.slots_out, "faces.out")) { + if (BMO_slot_buffer_len(op_sub.slots_out, "faces.out")) { BMO_slot_copy(&op_sub, slots_out, "faces.out", op, slots_out, "faces.out"); BMO_op_finish(bm, &op_sub); return; diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index 5449762b83c..8e4b0732feb 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -79,7 +79,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op) BMO_op_exec(bm, &op_attr); /* check if some faces couldn't be touched */ - if (BMO_slot_buffer_count(op_attr.slots_out, "faces_fail.out")) { + if (BMO_slot_buffer_len(op_attr.slots_out, "faces_fail.out")) { BMO_op_callf(bm, op->flag, "recalc_face_normals faces=%S", &op_attr, "faces_fail.out"); } BMO_op_finish(bm, &op_attr); diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index ffdce943d9f..0cedc2324f2 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -459,7 +459,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) } /* Allocate array to store possible vertices that will be dissolved. */ - int boundary_edges_len = BMO_slot_map_count(dupeop.slots_out, "boundary_map.out"); + int boundary_edges_len = BMO_slot_map_len(dupeop.slots_out, "boundary_map.out"); /* We do not know the real number of boundary vertices. */ int boundary_verts_len_maybe = 2 * boundary_edges_len; dissolve_verts = MEM_mallocN(boundary_verts_len_maybe * sizeof(*dissolve_verts), __func__); diff --git a/source/blender/bmesh/operators/bmo_fill_attribute.c b/source/blender/bmesh/operators/bmo_fill_attribute.c index e377fa6079b..5e8924c4a3b 100644 --- a/source/blender/bmesh/operators/bmo_fill_attribute.c +++ b/source/blender/bmesh/operators/bmo_fill_attribute.c @@ -161,7 +161,7 @@ void bmo_face_attribute_fill_exec(BMesh *bm, BMOperator *op) /* now we can copy adjacent data */ face_tot = bmesh_face_attribute_fill(bm, use_normals, use_data); - if (face_tot != BMO_slot_buffer_count(op->slots_in, "faces")) { + if (face_tot != BMO_slot_buffer_len(op->slots_in, "faces")) { /* any remaining tags will be skipped */ BMO_slot_buffer_from_enabled_hflag( bm, op, op->slots_out, "faces_fail.out", BM_FACE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/operators/bmo_fill_edgeloop.c b/source/blender/bmesh/operators/bmo_fill_edgeloop.c index 2b481542463..da4567d947b 100644 --- a/source/blender/bmesh/operators/bmo_fill_edgeloop.c +++ b/source/blender/bmesh/operators/bmo_fill_edgeloop.c @@ -35,7 +35,7 @@ void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op) { /* first collect an array of unique from the edges */ - const int tote = BMO_slot_buffer_count(op->slots_in, "edges"); + const int tote = BMO_slot_buffer_len(op->slots_in, "edges"); const int totv = tote; /* these should be the same */ BMVert **verts = MEM_mallocN(sizeof(*verts) * totv, __func__); diff --git a/source/blender/bmesh/operators/bmo_fill_holes.c b/source/blender/bmesh/operators/bmo_fill_holes.c index 64107fefe73..a24d81c5bdb 100644 --- a/source/blender/bmesh/operators/bmo_fill_holes.c +++ b/source/blender/bmesh/operators/bmo_fill_holes.c @@ -66,7 +66,7 @@ void bmo_holes_fill_exec(BMesh *bm, BMOperator *op) BMO_op_exec(bm, &op_attr); /* check if some faces couldn't be touched */ - if (BMO_slot_buffer_count(op_attr.slots_out, "faces_fail.out")) { + if (BMO_slot_buffer_len(op_attr.slots_out, "faces_fail.out")) { BMOIter siter; BMFace *f; diff --git a/source/blender/bmesh/operators/bmo_offset_edgeloops.c b/source/blender/bmesh/operators/bmo_offset_edgeloops.c index 98a8432cfb1..28f2c9a47aa 100644 --- a/source/blender/bmesh/operators/bmo_offset_edgeloops.c +++ b/source/blender/bmesh/operators/bmo_offset_edgeloops.c @@ -74,7 +74,7 @@ static BMFace *bm_face_split_walk_back(BMesh *bm, BMLoop *l_src, BMLoop **r_l) void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) { - const int edges_num = BMO_slot_buffer_count(op->slots_in, "edges"); + const int edges_num = BMO_slot_buffer_len(op->slots_in, "edges"); BMVert **verts; STACK_DECLARE(verts); int i; diff --git a/source/blender/bmesh/operators/bmo_planar_faces.c b/source/blender/bmesh/operators/bmo_planar_faces.c index c8f9d9a38dd..53cfc379269 100644 --- a/source/blender/bmesh/operators/bmo_planar_faces.c +++ b/source/blender/bmesh/operators/bmo_planar_faces.c @@ -41,7 +41,7 @@ void bmo_planar_faces_exec(BMesh *bm, BMOperator *op) { const float fac = BMO_slot_float_get(op->slots_in, "factor"); const int iterations = BMO_slot_int_get(op->slots_in, "iterations"); - const int faces_num = BMO_slot_buffer_count(op->slots_in, "faces"); + const int faces_num = BMO_slot_buffer_len(op->slots_in, "faces"); const float eps = 0.00001f; const float eps_sq = square_f(eps); diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index f47c8dfb405..8d5963cfb1c 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -788,7 +788,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op) } /** - * Fills first available UVmap with grid-like UVs for all faces OpFlag-ged by given flag. + * Fills first available UV-map with grid-like UV's for all faces with `oflag` set. * * \param bm: The BMesh to operate on * \param x_segments: The x-resolution of the grid @@ -1131,7 +1131,7 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset) } /** - * Fills first available UVmap with spherical projected UVs for all faces OpFlag-ged by given flag. + * Fills first available UV-map with spherical projected UVs for all faces with `oflag` set. * * \param bm: The BMesh to operate on * \param oflag: The flag to check faces with. @@ -1344,7 +1344,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) } /** - * Fills first available UVmap with 2D projected UVs for all faces OpFlag-ged by given flag. + * Fills first available UV-map with 2D projected UVs for all faces with `oflag` set. * * \param bm: The BMesh to operate on. * \param mat: The transform matrix applied to the created circle. @@ -1536,7 +1536,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) } /** - * Fills first available UVmap with cylinder/cone-like UVs for all faces OpFlag-ged by given flag. + * Fills first available UV-map with cylinder/cone-like UVs for all faces with `oflag` set. * * \param bm: The BMesh to operate on. * \param mat: The transform matrix applied to the created cone/cylinder. @@ -1712,7 +1712,7 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op) } /** - * Fills first available UVmap with cube-like UVs for all faces OpFlag-ged by given flag. + * Fills first available UV-map with cube-like UVs for all faces with `oflag` set. * * \note Expects tagged faces to be six quads. * \note Caller must order faces for correct alignment. diff --git a/source/blender/bmesh/operators/bmo_rotate_edges.c b/source/blender/bmesh/operators/bmo_rotate_edges.c index f05f6489c99..10dd9dcc9b7 100644 --- a/source/blender/bmesh/operators/bmo_rotate_edges.c +++ b/source/blender/bmesh/operators/bmo_rotate_edges.c @@ -234,7 +234,7 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op) { BMOIter siter; BMEdge *e; - const int edges_len = BMO_slot_buffer_count(op->slots_in, "edges"); + const int edges_len = BMO_slot_buffer_len(op->slots_in, "edges"); const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw"); const bool is_single = (edges_len == 1); short check_flag = is_single ? BM_EDGEROT_CHECK_EXISTS : diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index f6d612f31eb..9fa74bb64c3 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -74,7 +74,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) uint nors_tot; bool calc_winding = false; - sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_count(op->slots_in, "edges")); + sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_len(op->slots_in, "edges")); BMO_slot_vec_get(op->slots_in, "normal", normal); diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index c056302ca0f..7d2b6b73455 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -393,7 +393,7 @@ void bmo_smooth_vert_exec(BMesh *UNUSED(bm), BMOperator *op) BMIter iter; BMVert *v; BMEdge *e; - float(*cos)[3] = MEM_mallocN(sizeof(*cos) * BMO_slot_buffer_count(op->slots_in, "verts"), + float(*cos)[3] = MEM_mallocN(sizeof(*cos) * BMO_slot_buffer_len(op->slots_in, "verts"), __func__); float *co, *co2, clip_dist = BMO_slot_float_get(op->slots_in, "clip_dist"); const float fac = BMO_slot_float_get(op->slots_in, "factor"); diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c index 51af4d24e52..242b269ed47 100644 --- a/source/blender/bmesh/tools/bmesh_edgenet.c +++ b/source/blender/bmesh/tools/bmesh_edgenet.c @@ -17,7 +17,7 @@ /** \file * \ingroup bmesh * - * Edgenet Fill. + * Edge-net Fill. */ #include <limits.h> diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c index 1e9adea2615..eb56075e136 100644 --- a/source/blender/bmesh/tools/bmesh_intersect_edges.c +++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c @@ -938,7 +938,7 @@ bool BM_mesh_intersect_edges( } if (va_dest == v_other_dest) { - /* Edge/Edgenet to vertex - we can't split the face. */ + /* Edge/Edge-net to vertex - we can't split the face. */ break; } if (edgenet_len == 0 && BM_edge_exists(va_dest, v_other_dest)) { diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index ac59d832013..20b56ceb55f 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -59,6 +59,8 @@ set(SRC intern/COM_ChunkOrderHotspot.h intern/COM_CompositorContext.cc intern/COM_CompositorContext.h + intern/COM_ConstantFolder.cc + intern/COM_ConstantFolder.h intern/COM_Converter.cc intern/COM_Converter.h intern/COM_Debug.cc @@ -66,6 +68,7 @@ set(SRC intern/COM_Device.cc intern/COM_Device.h intern/COM_Enums.cc + intern/COM_Enums.h intern/COM_ExecutionGroup.cc intern/COM_ExecutionGroup.h intern/COM_ExecutionModel.cc @@ -82,6 +85,8 @@ set(SRC intern/COM_MetaData.h intern/COM_MultiThreadedOperation.cc intern/COM_MultiThreadedOperation.h + intern/COM_MultiThreadedRowOperation.cc + intern/COM_MultiThreadedRowOperation.h intern/COM_Node.cc intern/COM_Node.h intern/COM_NodeConverter.cc @@ -442,6 +447,8 @@ set(SRC operations/COM_BrightnessOperation.h operations/COM_ColorCorrectionOperation.cc operations/COM_ColorCorrectionOperation.h + operations/COM_ConstantOperation.cc + operations/COM_ConstantOperation.h operations/COM_GammaOperation.cc operations/COM_GammaOperation.h operations/COM_MixOperation.cc diff --git a/source/blender/compositor/intern/COM_BufferOperation.cc b/source/blender/compositor/intern/COM_BufferOperation.cc index 8464d01801f..90c97f2a9c7 100644 --- a/source/blender/compositor/intern/COM_BufferOperation.cc +++ b/source/blender/compositor/intern/COM_BufferOperation.cc @@ -23,6 +23,7 @@ namespace blender::compositor { BufferOperation::BufferOperation(MemoryBuffer *buffer, DataType data_type) { buffer_ = buffer; + inflated_buffer_ = nullptr; /* TODO: Implement a MemoryBuffer get_size() method returning a Size2d type. Shorten following * code to: set_resolution(buffer.get_size()) */ unsigned int resolution[2]; @@ -30,11 +31,30 @@ BufferOperation::BufferOperation(MemoryBuffer *buffer, DataType data_type) resolution[1] = buffer->getHeight(); setResolution(resolution); addOutputSocket(data_type); + flags.is_constant_operation = buffer_->is_a_single_elem(); +} + +const float *BufferOperation::get_constant_elem() +{ + BLI_assert(buffer_->is_a_single_elem()); + return buffer_->getBuffer(); } void *BufferOperation::initializeTileData(rcti * /*rect*/) { - return buffer_; + if (buffer_->is_a_single_elem() == false) { + return buffer_; + } + + if (!inflated_buffer_) { + inflated_buffer_ = buffer_->inflate(); + } + return inflated_buffer_; +} + +void BufferOperation::deinitExecution() +{ + delete inflated_buffer_; } void BufferOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) diff --git a/source/blender/compositor/intern/COM_BufferOperation.h b/source/blender/compositor/intern/COM_BufferOperation.h index f87cd4db94e..705264c37b7 100644 --- a/source/blender/compositor/intern/COM_BufferOperation.h +++ b/source/blender/compositor/intern/COM_BufferOperation.h @@ -18,18 +18,21 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_ConstantOperation.h" namespace blender::compositor { -class BufferOperation : public NodeOperation { +class BufferOperation : public ConstantOperation { private: MemoryBuffer *buffer_; + MemoryBuffer *inflated_buffer_; public: BufferOperation(MemoryBuffer *buffer, DataType data_type); + const float *get_constant_elem() override; void *initializeTileData(rcti *rect) override; + void deinitExecution() override; void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2]) override; }; diff --git a/source/blender/compositor/intern/COM_ConstantFolder.cc b/source/blender/compositor/intern/COM_ConstantFolder.cc new file mode 100644 index 00000000000..a9427013f87 --- /dev/null +++ b/source/blender/compositor/intern/COM_ConstantFolder.cc @@ -0,0 +1,191 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#include "BLI_rect.h" + +#include "COM_ConstantFolder.h" +#include "COM_ConstantOperation.h" +#include "COM_SetColorOperation.h" +#include "COM_SetValueOperation.h" +#include "COM_SetVectorOperation.h" +#include "COM_WorkScheduler.h" + +namespace blender::compositor { + +using Link = NodeOperationBuilder::Link; + +/** + * \param operations_builder: Contains all operations to fold. + * \param exec_system: Execution system. + */ +ConstantFolder::ConstantFolder(NodeOperationBuilder &operations_builder) + : operations_builder_(operations_builder) +{ + BLI_rcti_init(&max_area_, INT_MIN, INT_MAX, INT_MIN, INT_MAX); + BLI_rcti_init(&first_elem_area_, 0, 1, 0, 1); +} + +static bool is_constant_foldable(NodeOperation *operation) +{ + if (operation->get_flags().can_be_constant && !operation->get_flags().is_constant_operation) { + for (int i = 0; i < operation->getNumberOfInputSockets(); i++) { + if (!operation->get_input_operation(i)->get_flags().is_constant_operation) { + return false; + } + } + return true; + } + return false; +} + +static Vector<NodeOperation *> find_constant_foldable_operations(Span<NodeOperation *> operations) +{ + Vector<NodeOperation *> foldable_ops; + for (NodeOperation *op : operations) { + if (is_constant_foldable(op)) { + foldable_ops.append(op); + } + } + return foldable_ops; +} + +static ConstantOperation *create_constant_operation(DataType data_type, const float *constant_elem) +{ + switch (data_type) { + case DataType::Color: { + SetColorOperation *color_op = new SetColorOperation(); + color_op->setChannels(constant_elem); + return color_op; + } + case DataType::Vector: { + SetVectorOperation *vector_op = new SetVectorOperation(); + vector_op->setVector(constant_elem); + return vector_op; + } + case DataType::Value: { + SetValueOperation *value_op = new SetValueOperation(); + value_op->setValue(*constant_elem); + return value_op; + } + default: { + BLI_assert(!"Non implemented data type"); + return nullptr; + } + } +} + +ConstantOperation *ConstantFolder::fold_operation(NodeOperation *operation) +{ + const DataType data_type = operation->getOutputSocket()->getDataType(); + MemoryBuffer fold_buf(data_type, first_elem_area_); + Vector<MemoryBuffer *> input_bufs = get_constant_input_buffers(operation); + operation->render(&fold_buf, {first_elem_area_}, input_bufs); + + MemoryBuffer *constant_buf = create_constant_buffer(data_type); + constant_buf->copy_from(&fold_buf, first_elem_area_); + ConstantOperation *constant_op = create_constant_operation(data_type, constant_buf->getBuffer()); + operations_builder_.replace_operation_with_constant(operation, constant_op); + constant_buffers_.add_new(constant_op, constant_buf); + return constant_op; +} + +MemoryBuffer *ConstantFolder::create_constant_buffer(const DataType data_type) +{ + /* Create a single elem buffer with maximum area possible so readers can read any coordinate + * returning always same element. */ + return new MemoryBuffer(data_type, max_area_, true); +} + +Vector<MemoryBuffer *> ConstantFolder::get_constant_input_buffers(NodeOperation *operation) +{ + const int num_inputs = operation->getNumberOfInputSockets(); + Vector<MemoryBuffer *> inputs_bufs(num_inputs); + for (int i = 0; i < num_inputs; i++) { + BLI_assert(operation->get_input_operation(i)->get_flags().is_constant_operation); + ConstantOperation *constant_op = static_cast<ConstantOperation *>( + operation->get_input_operation(i)); + MemoryBuffer *constant_buf = constant_buffers_.lookup_or_add_cb(constant_op, [=] { + MemoryBuffer *buf = create_constant_buffer(constant_op->getOutputSocket()->getDataType()); + constant_op->render(buf, {first_elem_area_}, {}); + return buf; + }); + inputs_bufs[i] = constant_buf; + } + return inputs_bufs; +} + +/** Returns constant operations resulted from folded operations. */ +Vector<ConstantOperation *> ConstantFolder::try_fold_operations(Span<NodeOperation *> operations) +{ + Vector<NodeOperation *> foldable_ops = find_constant_foldable_operations(operations); + if (foldable_ops.size() == 0) { + return Vector<ConstantOperation *>(); + } + + Vector<ConstantOperation *> new_folds; + for (NodeOperation *op : foldable_ops) { + ConstantOperation *constant_op = fold_operation(op); + new_folds.append(constant_op); + } + return new_folds; +} + +/** + * Evaluate operations with constant elements into primitive constant operations. + */ +int ConstantFolder::fold_operations() +{ + WorkScheduler::start(operations_builder_.context()); + Vector<ConstantOperation *> last_folds = try_fold_operations( + operations_builder_.get_operations()); + int folds_count = last_folds.size(); + while (last_folds.size() > 0) { + Vector<NodeOperation *> ops_to_fold; + for (ConstantOperation *fold : last_folds) { + get_operation_output_operations(fold, ops_to_fold); + } + last_folds = try_fold_operations(ops_to_fold); + folds_count += last_folds.size(); + } + WorkScheduler::stop(); + + delete_constant_buffers(); + + return folds_count; +} + +void ConstantFolder::delete_constant_buffers() +{ + for (MemoryBuffer *buf : constant_buffers_.values()) { + delete buf; + } + constant_buffers_.clear(); +} + +void ConstantFolder::get_operation_output_operations(NodeOperation *operation, + Vector<NodeOperation *> &r_outputs) +{ + const Vector<Link> &links = operations_builder_.get_links(); + for (const Link &link : links) { + if (&link.from()->getOperation() == operation) { + r_outputs.append(&link.to()->getOperation()); + } + } +} + +} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ConstantFolder.h b/source/blender/compositor/intern/COM_ConstantFolder.h new file mode 100644 index 00000000000..2432e859a5a --- /dev/null +++ b/source/blender/compositor/intern/COM_ConstantFolder.h @@ -0,0 +1,64 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#pragma once + +#include "BLI_map.hh" +#include "BLI_set.hh" +#include "BLI_vector.hh" + +#include "COM_NodeOperationBuilder.h" +#include "COM_defines.h" + +namespace blender::compositor { + +class NodeOperation; +class ConstantOperation; +class MemoryBuffer; + +/** + * Evaluates all operations with constant elements into primitive constant operations + * (Value/Vector/Color). + */ +class ConstantFolder { + private: + NodeOperationBuilder &operations_builder_; + + /** Constant operations buffers. */ + Map<ConstantOperation *, MemoryBuffer *> constant_buffers_; + + rcti max_area_; + rcti first_elem_area_; + + public: + ConstantFolder(NodeOperationBuilder &operations_builder); + int fold_operations(); + + private: + Vector<ConstantOperation *> try_fold_operations(Span<NodeOperation *> operations); + ConstantOperation *fold_operation(NodeOperation *operation); + + MemoryBuffer *create_constant_buffer(DataType data_type); + Vector<MemoryBuffer *> get_constant_input_buffers(NodeOperation *operation); + void delete_constant_buffers(); + + void get_operation_output_operations(NodeOperation *operation, + Vector<NodeOperation *> &r_outputs); +}; + +} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc index 4cf7e09a7d8..abef4517b3e 100644 --- a/source/blender/compositor/intern/COM_Debug.cc +++ b/source/blender/compositor/intern/COM_Debug.cc @@ -37,6 +37,7 @@ extern "C" { #include "COM_Node.h" #include "COM_ReadBufferOperation.h" +#include "COM_SetValueOperation.h" #include "COM_ViewerOperation.h" #include "COM_WriteBufferOperation.h" @@ -49,6 +50,15 @@ std::string DebugInfo::m_current_node_name; std::string DebugInfo::m_current_op_name; DebugInfo::GroupStateMap DebugInfo::m_group_states; +static std::string operation_class_name(NodeOperation *op) +{ + std::string full_name = typeid(*op).name(); + /* Remove name-spaces. */ + size_t pos = full_name.find_last_of(':'); + BLI_assert(pos != std::string::npos); + return full_name.substr(pos + 1); +} + std::string DebugInfo::node_name(const Node *node) { NodeNameMap::const_iterator it = m_node_names.find(node); @@ -135,15 +145,23 @@ int DebugInfo::graphviz_operation(const ExecutionSystem *system, len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|"); } + if (COM_GRAPHVIZ_SHOW_NODE_NAME) { + std::string op_node_name = operation->get_name(); + if (!op_node_name.empty()) { + len += snprintf( + str + len, maxlen > len ? maxlen - len : 0, "%s\\n", (op_node_name + " Node").c_str()); + } + } + len += snprintf(str + len, maxlen > len ? maxlen - len : 0, - "%s\\n(%s)", - m_op_names[operation].c_str(), - typeid(*operation).name()); + "%s\\n", + operation_class_name(operation).c_str()); len += snprintf(str + len, maxlen > len ? maxlen - len : 0, - " (%u,%u)", + "#%d (%u,%u)", + operation->get_id(), operation->getWidth(), operation->getHeight()); @@ -159,7 +177,13 @@ int DebugInfo::graphviz_operation(const ExecutionSystem *system, len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "<OUT_%p>", socket); switch (socket->getDataType()) { case DataType::Value: - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value"); + if (typeid(*operation) == typeid(SetValueOperation)) { + const float value = ((SetValueOperation *)operation)->getValue(); + len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value\\n%12.4g", value); + } + else { + len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value"); + } break; case DataType::Vector: len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Vector"); @@ -401,7 +425,7 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma return (len < maxlen); } -void DebugInfo::graphviz(const ExecutionSystem *system) +void DebugInfo::graphviz(const ExecutionSystem *system, StringRefNull name) { if (!COM_EXPORT_GRAPHVIZ) { return; @@ -411,7 +435,12 @@ void DebugInfo::graphviz(const ExecutionSystem *system) char basename[FILE_MAX]; char filename[FILE_MAX]; - BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index); + if (name.is_empty()) { + BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index); + } + else { + BLI_strncpy(basename, (name + ".dot").c_str(), sizeof(basename)); + } BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), basename); m_file_index++; diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h index 0de3a5e39dc..53461e13f48 100644 --- a/source/blender/compositor/intern/COM_Debug.h +++ b/source/blender/compositor/intern/COM_Debug.h @@ -28,6 +28,8 @@ namespace blender::compositor { static constexpr bool COM_EXPORT_GRAPHVIZ = false; +static constexpr bool COM_GRAPHVIZ_SHOW_NODE_NAME = false; + class Node; class ExecutionSystem; class ExecutionGroup; @@ -116,7 +118,7 @@ class DebugInfo { } }; - static void graphviz(const ExecutionSystem *system); + static void graphviz(const ExecutionSystem *system, StringRefNull name = ""); protected: static int graphviz_operation(const ExecutionSystem *system, diff --git a/source/blender/compositor/intern/COM_ExecutionModel.cc b/source/blender/compositor/intern/COM_ExecutionModel.cc index 4d7f62e091b..b75b277e92c 100644 --- a/source/blender/compositor/intern/COM_ExecutionModel.cc +++ b/source/blender/compositor/intern/COM_ExecutionModel.cc @@ -39,10 +39,4 @@ ExecutionModel::ExecutionModel(CompositorContext &context, Span<NodeOperation *> border_.render_border = &rd->border; } -bool ExecutionModel::is_breaked() const -{ - const bNodeTree *btree = context_.getbNodeTree(); - return btree->test_break(btree->tbh); -} - } // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ExecutionModel.h b/source/blender/compositor/intern/COM_ExecutionModel.h index 9e8466b9282..452861ae4be 100644 --- a/source/blender/compositor/intern/COM_ExecutionModel.h +++ b/source/blender/compositor/intern/COM_ExecutionModel.h @@ -67,15 +67,6 @@ class ExecutionModel { virtual void execute(ExecutionSystem &exec_system) = 0; - virtual void execute_work(const rcti &UNUSED(work_rect), - std::function<void(const rcti &split_rect)> UNUSED(work_func)) - { - BLI_assert(!"Method not supported by current execution model"); - } - - protected: - bool is_breaked() const; - #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:BaseExecutionModel") #endif diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index a12ec774032..dfcf76cdd0a 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -63,8 +63,11 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, this->m_context.setViewSettings(viewSettings); this->m_context.setDisplaySettings(displaySettings); + BLI_mutex_init(&work_mutex_); + BLI_condition_init(&work_finished_cond_); + { - NodeOperationBuilder builder(&m_context, editingtree); + NodeOperationBuilder builder(&m_context, editingtree, this); builder.convertToOperations(this); } @@ -83,6 +86,9 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, ExecutionSystem::~ExecutionSystem() { + BLI_condition_end(&work_finished_cond_); + BLI_mutex_end(&work_mutex_); + delete execution_model_; for (NodeOperation *operation : m_operations) { @@ -109,10 +115,74 @@ void ExecutionSystem::execute() execution_model_->execute(*this); } +/** + * Multi-threadedly execute given work function passing work_rect splits as argument. + */ void ExecutionSystem::execute_work(const rcti &work_rect, std::function<void(const rcti &split_rect)> work_func) { - execution_model_->execute_work(work_rect, work_func); + if (is_breaked()) { + return; + } + + /* Split work vertically to maximize continuous memory. */ + const int work_height = BLI_rcti_size_y(&work_rect); + const int num_sub_works = MIN2(WorkScheduler::get_num_cpu_threads(), work_height); + const int split_height = num_sub_works == 0 ? 0 : work_height / num_sub_works; + int remaining_height = work_height - split_height * num_sub_works; + + Vector<WorkPackage> sub_works(num_sub_works); + int sub_work_y = work_rect.ymin; + int num_sub_works_finished = 0; + for (int i = 0; i < num_sub_works; i++) { + int sub_work_height = split_height; + + /* Distribute remaining height between sub-works. */ + if (remaining_height > 0) { + sub_work_height++; + remaining_height--; + } + + WorkPackage &sub_work = sub_works[i]; + sub_work.type = eWorkPackageType::CustomFunction; + sub_work.execute_fn = [=, &work_func, &work_rect]() { + if (is_breaked()) { + return; + } + rcti split_rect; + BLI_rcti_init( + &split_rect, work_rect.xmin, work_rect.xmax, sub_work_y, sub_work_y + sub_work_height); + work_func(split_rect); + }; + sub_work.executed_fn = [&]() { + BLI_mutex_lock(&work_mutex_); + num_sub_works_finished++; + if (num_sub_works_finished == num_sub_works) { + BLI_condition_notify_one(&work_finished_cond_); + } + BLI_mutex_unlock(&work_mutex_); + }; + WorkScheduler::schedule(&sub_work); + sub_work_y += sub_work_height; + } + BLI_assert(sub_work_y == work_rect.ymax); + + WorkScheduler::finish(); + + /* Ensure all sub-works finished. + * TODO: This a workaround for WorkScheduler::finish() not waiting all works on queue threading + * model. Sync code should be removed once it's fixed. */ + BLI_mutex_lock(&work_mutex_); + if (num_sub_works_finished < num_sub_works) { + BLI_condition_wait(&work_finished_cond_, &work_mutex_); + } + BLI_mutex_unlock(&work_mutex_); +} + +bool ExecutionSystem::is_breaked() const +{ + const bNodeTree *btree = m_context.getbNodeTree(); + return btree->test_break(btree->tbh); } } // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index e106209651c..38c3432a8ec 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -150,7 +150,9 @@ class ExecutionSystem { */ ExecutionModel *execution_model_; - private: // methods + ThreadMutex work_mutex_; + ThreadCondition work_finished_cond_; + public: /** * \brief Create a new ExecutionSystem and initialize it with the @@ -199,6 +201,8 @@ class ExecutionSystem { void execute_work(const rcti &work_rect, std::function<void(const rcti &split_rect)> work_func); + bool is_breaked() const; + private: /* allow the DebugInfo class to look at internals */ friend class DebugInfo; diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc index 21075bb7255..3b0a9172871 100644 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc +++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc @@ -35,24 +35,13 @@ FullFrameExecutionModel::FullFrameExecutionModel(CompositorContext &context, Span<NodeOperation *> operations) : ExecutionModel(context, operations), active_buffers_(shared_buffers), - num_operations_finished_(0), - work_mutex_(), - work_finished_cond_() + num_operations_finished_(0) { priorities_.append(eCompositorPriority::High); if (!context.isFastCalculation()) { priorities_.append(eCompositorPriority::Medium); priorities_.append(eCompositorPriority::Low); } - - BLI_mutex_init(&work_mutex_); - BLI_condition_init(&work_finished_cond_); -} - -FullFrameExecutionModel::~FullFrameExecutionModel() -{ - BLI_condition_end(&work_finished_cond_); - BLI_mutex_end(&work_mutex_); } void FullFrameExecutionModel::execute(ExecutionSystem &exec_system) @@ -60,10 +49,10 @@ void FullFrameExecutionModel::execute(ExecutionSystem &exec_system) const bNodeTree *node_tree = this->context_.getbNodeTree(); node_tree->stats_draw(node_tree->sdh, TIP_("Compositing | Initializing execution")); - DebugInfo::graphviz(&exec_system); + DebugInfo::graphviz(&exec_system, "compositor_prior_rendering"); determine_areas_to_render_and_reads(); - render_operations(exec_system); + render_operations(); } void FullFrameExecutionModel::determine_areas_to_render_and_reads() @@ -101,20 +90,18 @@ MemoryBuffer *FullFrameExecutionModel::create_operation_buffer(NodeOperation *op BLI_rcti_init(&op_rect, 0, op->getWidth(), 0, op->getHeight()); const DataType data_type = op->getOutputSocket(0)->getDataType(); - /* TODO: We should check if the operation is constant instead of is_set_operation. Finding a way - * to know if an operation is constant has to be implemented yet. */ - const bool is_a_single_elem = op->get_flags().is_set_operation; + const bool is_a_single_elem = op->get_flags().is_constant_operation; return new MemoryBuffer(data_type, op_rect, is_a_single_elem); } -void FullFrameExecutionModel::render_operation(NodeOperation *op, ExecutionSystem &exec_system) +void FullFrameExecutionModel::render_operation(NodeOperation *op) { Vector<MemoryBuffer *> input_bufs = get_input_buffers(op); const bool has_outputs = op->getNumberOfOutputSockets() > 0; MemoryBuffer *op_buf = has_outputs ? create_operation_buffer(op) : nullptr; Span<rcti> areas = active_buffers_.get_areas_to_render(op); - op->render(op_buf, areas, input_bufs, exec_system); + op->render(op_buf, areas, input_bufs); active_buffers_.set_rendered_buffer(op, std::unique_ptr<MemoryBuffer>(op_buf)); operation_finished(op); @@ -123,7 +110,7 @@ void FullFrameExecutionModel::render_operation(NodeOperation *op, ExecutionSyste /** * Render output operations in order of priority. */ -void FullFrameExecutionModel::render_operations(ExecutionSystem &exec_system) +void FullFrameExecutionModel::render_operations() { const bool is_rendering = context_.isRendering(); @@ -131,8 +118,8 @@ void FullFrameExecutionModel::render_operations(ExecutionSystem &exec_system) for (eCompositorPriority priority : priorities_) { for (NodeOperation *op : operations_) { if (op->isOutputOperation(is_rendering) && op->getRenderPriority() == priority) { - render_output_dependencies(op, exec_system); - render_operation(op, exec_system); + render_output_dependencies(op); + render_operation(op); } } } @@ -166,14 +153,13 @@ static Vector<NodeOperation *> get_operation_dependencies(NodeOperation *operati return dependencies; } -void FullFrameExecutionModel::render_output_dependencies(NodeOperation *output_op, - ExecutionSystem &exec_system) +void FullFrameExecutionModel::render_output_dependencies(NodeOperation *output_op) { BLI_assert(output_op->isOutputOperation(context_.isRendering())); Vector<NodeOperation *> dependencies = get_operation_dependencies(output_op); for (NodeOperation *op : dependencies) { if (!active_buffers_.is_operation_rendered(op)) { - render_operation(op, exec_system); + render_operation(op); } } } @@ -266,70 +252,6 @@ void FullFrameExecutionModel::get_output_render_area(NodeOperation *output_op, r } } -/** - * Multi-threadedly execute given work function passing work_rect splits as argument. - */ -void FullFrameExecutionModel::execute_work(const rcti &work_rect, - std::function<void(const rcti &split_rect)> work_func) -{ - if (is_breaked()) { - return; - } - - /* Split work vertically to maximize continuous memory. */ - const int work_height = BLI_rcti_size_y(&work_rect); - const int num_sub_works = MIN2(WorkScheduler::get_num_cpu_threads(), work_height); - const int split_height = num_sub_works == 0 ? 0 : work_height / num_sub_works; - int remaining_height = work_height - split_height * num_sub_works; - - Vector<WorkPackage> sub_works(num_sub_works); - int sub_work_y = work_rect.ymin; - int num_sub_works_finished = 0; - for (int i = 0; i < num_sub_works; i++) { - int sub_work_height = split_height; - - /* Distribute remaining height between sub-works. */ - if (remaining_height > 0) { - sub_work_height++; - remaining_height--; - } - - WorkPackage &sub_work = sub_works[i]; - sub_work.type = eWorkPackageType::CustomFunction; - sub_work.execute_fn = [=, &work_func, &work_rect]() { - if (is_breaked()) { - return; - } - rcti split_rect; - BLI_rcti_init( - &split_rect, work_rect.xmin, work_rect.xmax, sub_work_y, sub_work_y + sub_work_height); - work_func(split_rect); - }; - sub_work.executed_fn = [&]() { - BLI_mutex_lock(&work_mutex_); - num_sub_works_finished++; - if (num_sub_works_finished == num_sub_works) { - BLI_condition_notify_one(&work_finished_cond_); - } - BLI_mutex_unlock(&work_mutex_); - }; - WorkScheduler::schedule(&sub_work); - sub_work_y += sub_work_height; - } - BLI_assert(sub_work_y == work_rect.ymax); - - WorkScheduler::finish(); - - /* Ensure all sub-works finished. - * TODO: This a workaround for WorkScheduler::finish() not waiting all works on queue threading - * model. Sync code should be removed once it's fixed. */ - BLI_mutex_lock(&work_mutex_); - if (num_sub_works_finished < num_sub_works) { - BLI_condition_wait(&work_finished_cond_, &work_mutex_); - } - BLI_mutex_unlock(&work_mutex_); -} - void FullFrameExecutionModel::operation_finished(NodeOperation *operation) { /* Report inputs reads so that buffers may be freed/reused. */ diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h index e68ad93b407..f75d4f1afdc 100644 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h +++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h @@ -50,27 +50,20 @@ class FullFrameExecutionModel : public ExecutionModel { */ Vector<eCompositorPriority> priorities_; - ThreadMutex work_mutex_; - ThreadCondition work_finished_cond_; - public: FullFrameExecutionModel(CompositorContext &context, SharedOperationBuffers &shared_buffers, Span<NodeOperation *> operations); - ~FullFrameExecutionModel(); void execute(ExecutionSystem &exec_system) override; - void execute_work(const rcti &work_rect, - std::function<void(const rcti &split_rect)> work_func) override; - private: void determine_areas_to_render_and_reads(); - void render_operations(ExecutionSystem &exec_system); - void render_output_dependencies(NodeOperation *output_op, ExecutionSystem &exec_system); + void render_operations(); + void render_output_dependencies(NodeOperation *output_op); Vector<MemoryBuffer *> get_input_buffers(NodeOperation *op); MemoryBuffer *create_operation_buffer(NodeOperation *op); - void render_operation(NodeOperation *op, ExecutionSystem &exec_system); + void render_operation(NodeOperation *op); void operation_finished(NodeOperation *operation); diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc index 44d3f059374..c7bddddd0e6 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc @@ -129,6 +129,18 @@ void MemoryBuffer::clear() memset(m_buffer, 0, buffer_len() * m_num_channels * sizeof(float)); } +/** + * Converts a single elem buffer to a full size buffer (allocates memory for all + * elements in resolution). + */ +MemoryBuffer *MemoryBuffer::inflate() const +{ + BLI_assert(is_a_single_elem()); + MemoryBuffer *inflated = new MemoryBuffer(this->m_datatype, this->m_rect, false); + inflated->copy_from(this, this->m_rect); + return inflated; +} + float MemoryBuffer::get_max_value() const { float result = this->m_buffer[0]; diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index fdfd1c1c37b..89068a7b734 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -247,6 +247,8 @@ class MemoryBuffer { return this->m_buffer; } + MemoryBuffer *inflate() const; + inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y) { const int w = getWidth(); diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.cc b/source/blender/compositor/intern/COM_MultiThreadedOperation.cc index e6e98d69b36..7ccf6f76d9f 100644 --- a/source/blender/compositor/intern/COM_MultiThreadedOperation.cc +++ b/source/blender/compositor/intern/COM_MultiThreadedOperation.cc @@ -12,12 +12,11 @@ MultiThreadedOperation::MultiThreadedOperation() void MultiThreadedOperation::update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> inputs, - ExecutionSystem &exec_system) + Span<MemoryBuffer *> inputs) { for (current_pass_ = 0; current_pass_ < num_passes_; current_pass_++) { update_memory_buffer_started(output, area, inputs); - exec_system.execute_work(area, [=](const rcti &split_rect) { + exec_system_->execute_work(area, [=](const rcti &split_rect) { update_memory_buffer_partial(output, split_rect, inputs); }); update_memory_buffer_finished(output, area, inputs); diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.h b/source/blender/compositor/intern/COM_MultiThreadedOperation.h index ad09c4df089..a7e574ca745 100644 --- a/source/blender/compositor/intern/COM_MultiThreadedOperation.h +++ b/source/blender/compositor/intern/COM_MultiThreadedOperation.h @@ -64,8 +64,7 @@ class MultiThreadedOperation : public NodeOperation { private: void update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> inputs, - ExecutionSystem &exec_system) override; + Span<MemoryBuffer *> inputs) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MultiThreadedRowOperation.cc b/source/blender/compositor/intern/COM_MultiThreadedRowOperation.cc new file mode 100644 index 00000000000..6bf318bb96b --- /dev/null +++ b/source/blender/compositor/intern/COM_MultiThreadedRowOperation.cc @@ -0,0 +1,50 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#include "COM_MultiThreadedRowOperation.h" + +namespace blender::compositor { + +MultiThreadedRowOperation::PixelCursor::PixelCursor(const int num_inputs) + : out(nullptr), out_stride(0), row_end(nullptr), ins(num_inputs), in_strides(num_inputs) +{ +} + +void MultiThreadedRowOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) +{ + BLI_assert(output != nullptr); + const int width = BLI_rcti_size_x(&area); + PixelCursor p(inputs.size()); + p.out_stride = output->elem_stride; + for (int i = 0; i < p.in_strides.size(); i++) { + p.in_strides[i] = inputs[i]->elem_stride; + } + + for (int y = area.ymin; y < area.ymax; y++) { + p.out = output->get_elem(area.xmin, y); + for (int i = 0; i < p.ins.size(); i++) { + p.ins[i] = inputs[i]->get_elem(area.xmin, y); + } + p.row_end = p.out + width * p.out_stride; + update_memory_buffer_row(p); + } +} + +} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MultiThreadedRowOperation.h b/source/blender/compositor/intern/COM_MultiThreadedRowOperation.h new file mode 100644 index 00000000000..3daa9eec474 --- /dev/null +++ b/source/blender/compositor/intern/COM_MultiThreadedRowOperation.h @@ -0,0 +1,60 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#pragma once + +#include "COM_MultiThreadedOperation.h" + +namespace blender::compositor { + +/** + * Executes buffer updates per row. To be inherited only by operations with correlated coordinates + * between inputs and output. + */ +class MultiThreadedRowOperation : public MultiThreadedOperation { + protected: + struct PixelCursor { + float *out; + int out_stride; + const float *row_end; + Array<const float *> ins; + Array<int> in_strides; + + public: + PixelCursor(int num_inputs); + + void next() + { + BLI_assert(out < row_end); + out += out_stride; + for (int i = 0; i < ins.size(); i++) { + ins[i] += in_strides[i]; + } + } + }; + + protected: + virtual void update_memory_buffer_row(PixelCursor &p) = 0; + + private: + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) final; +}; + +} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc index b943ab6af7f..6484c75f364 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cc +++ b/source/blender/compositor/intern/COM_NodeOperation.cc @@ -226,18 +226,16 @@ void NodeOperation::get_area_of_interest(NodeOperation *input_op, * \param output_buf: Buffer to write result to. * \param areas: Areas within this operation bounds to render. * \param inputs_bufs: Inputs operations buffers. - * \param exec_system: Execution system. */ void NodeOperation::render(MemoryBuffer *output_buf, Span<rcti> areas, - Span<MemoryBuffer *> inputs_bufs, - ExecutionSystem &exec_system) + Span<MemoryBuffer *> inputs_bufs) { if (get_flags().is_fullframe_operation) { - render_full_frame(output_buf, areas, inputs_bufs, exec_system); + render_full_frame(output_buf, areas, inputs_bufs); } else { - render_full_frame_fallback(output_buf, areas, inputs_bufs, exec_system); + render_full_frame_fallback(output_buf, areas, inputs_bufs); } } @@ -246,12 +244,11 @@ void NodeOperation::render(MemoryBuffer *output_buf, */ void NodeOperation::render_full_frame(MemoryBuffer *output_buf, Span<rcti> areas, - Span<MemoryBuffer *> inputs_bufs, - ExecutionSystem &exec_system) + Span<MemoryBuffer *> inputs_bufs) { initExecution(); for (const rcti &area : areas) { - update_memory_buffer(output_buf, area, inputs_bufs, exec_system); + update_memory_buffer(output_buf, area, inputs_bufs); } deinitExecution(); } @@ -261,8 +258,7 @@ void NodeOperation::render_full_frame(MemoryBuffer *output_buf, */ void NodeOperation::render_full_frame_fallback(MemoryBuffer *output_buf, Span<rcti> areas, - Span<MemoryBuffer *> inputs_bufs, - ExecutionSystem &exec_system) + Span<MemoryBuffer *> inputs_bufs) { Vector<NodeOperationOutput *> orig_input_links = replace_inputs_with_buffers(inputs_bufs); @@ -274,7 +270,7 @@ void NodeOperation::render_full_frame_fallback(MemoryBuffer *output_buf, } else { for (const rcti &rect : areas) { - exec_system.execute_work(rect, [=](const rcti &split_rect) { + exec_system_->execute_work(rect, [=](const rcti &split_rect) { rcti tile_rect = split_rect; if (is_output_operation) { executeRegion(&tile_rect, 0); @@ -328,6 +324,7 @@ Vector<NodeOperationOutput *> NodeOperation::replace_inputs_with_buffers( BufferOperation *buffer_op = new BufferOperation(inputs_bufs[i], input_socket->getDataType()); orig_links[i] = input_socket->getLink(); input_socket->setLink(buffer_op->getOutputSocket()); + buffer_op->initExecution(); } return orig_links; } @@ -340,6 +337,7 @@ void NodeOperation::remove_buffers_and_restore_original_inputs( NodeOperation *buffer_op = get_input_operation(i); BLI_assert(buffer_op != nullptr); BLI_assert(typeid(*buffer_op) == typeid(BufferOperation)); + buffer_op->deinitExecution(); NodeOperationInput *input_socket = getInputSocket(i); input_socket->setLink(original_inputs_links[i]); delete buffer_op; @@ -443,6 +441,12 @@ std::ostream &operator<<(std::ostream &os, const NodeOperationFlags &node_operat if (node_operation_flags.is_fullframe_operation) { os << "full_frame,"; } + if (node_operation_flags.is_constant_operation) { + os << "contant_operation,"; + } + if (node_operation_flags.can_be_constant) { + os << "can_be_constant,"; + } return os; } diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 5ae0aae67d5..fb9ec1e7a83 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -221,6 +221,7 @@ struct NodeOperationFlags { /** * Is this a set operation (value, color, vector). + * TODO: To be replaced by is_constant_operation flag once tiled implementation is removed. */ bool is_set_operation : 1; bool is_write_buffer_operation : 1; @@ -242,6 +243,17 @@ struct NodeOperationFlags { */ bool is_fullframe_operation : 1; + /** + * Whether operation is a primitive constant operation (Color/Vector/Value). + */ + bool is_constant_operation : 1; + + /** + * Whether operation have constant elements/pixels values when all its inputs are constant + * operations. + */ + bool can_be_constant : 1; + NodeOperationFlags() { complex = false; @@ -258,6 +270,8 @@ struct NodeOperationFlags { is_preview_operation = false; use_datatype_conversion = true; is_fullframe_operation = false; + is_constant_operation = false; + can_be_constant = false; } }; @@ -316,6 +330,8 @@ class NodeOperation { */ NodeOperationFlags flags; + ExecutionSystem *exec_system_; + public: virtual ~NodeOperation() { @@ -402,6 +418,12 @@ class NodeOperation { { this->m_btree = tree; } + + void set_execution_system(ExecutionSystem *system) + { + exec_system_ = system; + } + virtual void initExecution(); /** @@ -569,18 +591,14 @@ class NodeOperation { /** \name Full Frame Methods * \{ */ - void render(MemoryBuffer *output_buf, - Span<rcti> areas, - Span<MemoryBuffer *> inputs_bufs, - ExecutionSystem &exec_system); + void render(MemoryBuffer *output_buf, Span<rcti> areas, Span<MemoryBuffer *> inputs_bufs); /** * Executes operation updating output memory buffer. Single-threaded calls. */ virtual void update_memory_buffer(MemoryBuffer *UNUSED(output), const rcti &UNUSED(area), - Span<MemoryBuffer *> UNUSED(inputs), - ExecutionSystem &UNUSED(exec_system)) + Span<MemoryBuffer *> UNUSED(inputs)) { } @@ -678,13 +696,11 @@ class NodeOperation { void render_full_frame(MemoryBuffer *output_buf, Span<rcti> areas, - Span<MemoryBuffer *> inputs_bufs, - ExecutionSystem &exec_system); + Span<MemoryBuffer *> inputs_bufs); void render_full_frame_fallback(MemoryBuffer *output_buf, Span<rcti> areas, - Span<MemoryBuffer *> inputs, - ExecutionSystem &exec_system); + Span<MemoryBuffer *> inputs); void render_tile(MemoryBuffer *output_buf, rcti *tile_rect); Vector<NodeOperationOutput *> replace_inputs_with_buffers(Span<MemoryBuffer *> inputs_bufs); void remove_buffers_and_restore_original_inputs( diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc index 3036e3f55dd..10a91bbcd3e 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc @@ -36,12 +36,15 @@ #include "COM_ViewerOperation.h" #include "COM_WriteBufferOperation.h" +#include "COM_ConstantFolder.h" #include "COM_NodeOperationBuilder.h" /* own include */ namespace blender::compositor { -NodeOperationBuilder::NodeOperationBuilder(const CompositorContext *context, bNodeTree *b_nodetree) - : m_context(context), m_current_node(nullptr), m_active_viewer(nullptr) +NodeOperationBuilder::NodeOperationBuilder(const CompositorContext *context, + bNodeTree *b_nodetree, + ExecutionSystem *system) + : m_context(context), exec_system_(system), m_current_node(nullptr), m_active_viewer(nullptr) { m_graph.from_bNodeTree(*context, b_nodetree); } @@ -97,6 +100,15 @@ void NodeOperationBuilder::convertToOperations(ExecutionSystem *system) add_datatype_conversions(); + if (m_context->get_execution_model() == eExecutionModel::FullFrame) { + /* Copy operations to system. Needed for graphviz. */ + system->set_operations(m_operations, {}); + + DebugInfo::graphviz(system, "compositor_prior_folding"); + ConstantFolder folder(*this); + folder.fold_operations(); + } + determineResolutions(); if (m_context->get_execution_model() == eExecutionModel::Tiled) { @@ -130,6 +142,29 @@ void NodeOperationBuilder::addOperation(NodeOperation *operation) operation->set_name(m_current_node->getbNode()->name); } operation->set_execution_model(m_context->get_execution_model()); + operation->set_execution_system(exec_system_); +} + +void NodeOperationBuilder::replace_operation_with_constant(NodeOperation *operation, + ConstantOperation *constant_operation) +{ + BLI_assert(constant_operation->getNumberOfInputSockets() == 0); + int i = 0; + while (i < m_links.size()) { + Link &link = m_links[i]; + if (&link.to()->getOperation() == operation) { + link.to()->setLink(nullptr); + m_links.remove(i); + continue; + } + + if (&link.from()->getOperation() == operation) { + link.to()->setLink(constant_operation->getOutputSocket()); + m_links[i] = Link(constant_operation->getOutputSocket(), link.to()); + } + i++; + } + addOperation(constant_operation); } void NodeOperationBuilder::mapInputSocket(NodeInput *node_socket, diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h index b2fb822af25..1f76765c846 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.h +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.h @@ -41,6 +41,7 @@ class NodeOperationOutput; class PreviewOperation; class WriteBufferOperation; class ViewerOperation; +class ConstantOperation; class NodeOperationBuilder { public: @@ -67,6 +68,7 @@ class NodeOperationBuilder { private: const CompositorContext *m_context; NodeGraph m_graph; + ExecutionSystem *exec_system_; Vector<NodeOperation *> m_operations; Vector<Link> m_links; @@ -86,7 +88,9 @@ class NodeOperationBuilder { ViewerOperation *m_active_viewer; public: - NodeOperationBuilder(const CompositorContext *context, bNodeTree *b_nodetree); + NodeOperationBuilder(const CompositorContext *context, + bNodeTree *b_nodetree, + ExecutionSystem *system); const CompositorContext &context() const { @@ -96,6 +100,8 @@ class NodeOperationBuilder { void convertToOperations(ExecutionSystem *system); void addOperation(NodeOperation *operation); + void replace_operation_with_constant(NodeOperation *operation, + ConstantOperation *constant_operation); /** Map input socket of the current node to an operation socket */ void mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket); diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc index 157ded943d6..8e49bf34b51 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ b/source/blender/compositor/intern/COM_WorkScheduler.cc @@ -126,7 +126,7 @@ static void *thread_execute_gpu(void *data) return nullptr; } -static void opencl_start(CompositorContext &context) +static void opencl_start(const CompositorContext &context) { if (context.getHasActiveOpenCLDevices()) { g_work_scheduler.opencl.queue = BLI_thread_queue_init(); @@ -458,7 +458,7 @@ void WorkScheduler::schedule(WorkPackage *package) } } -void WorkScheduler::start(CompositorContext &context) +void WorkScheduler::start(const CompositorContext &context) { if (COM_is_opencl_enabled()) { opencl_start(context); diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h index be88859be7c..297943aa63b 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.h +++ b/source/blender/compositor/intern/COM_WorkScheduler.h @@ -65,7 +65,7 @@ struct WorkScheduler { * for every device a thread is created. * \see initialize Initialization and query of the number of devices */ - static void start(CompositorContext &context); + static void start(const CompositorContext &context); /** * \brief stop the execution diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc index d1d3752e402..aee8c0d52e8 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc @@ -41,6 +41,7 @@ ColorBalanceASCCDLOperation::ColorBalanceASCCDLOperation() this->m_inputValueOperation = nullptr; this->m_inputColorOperation = nullptr; this->setResolutionInputSocketIndex(1); + flags.can_be_constant = true; } void ColorBalanceASCCDLOperation::initExecution() @@ -76,6 +77,23 @@ void ColorBalanceASCCDLOperation::executePixelSampled(float output[4], output[3] = inputColor[3]; } +void ColorBalanceASCCDLOperation::update_memory_buffer_row(PixelCursor &p) +{ + for (; p.out < p.row_end; p.next()) { + const float *in_factor = p.ins[0]; + const float *in_color = p.ins[1]; + const float fac = MIN2(1.0f, in_factor[0]); + const float fac_m = 1.0f - fac; + p.out[0] = fac_m * in_color[0] + + fac * colorbalance_cdl(in_color[0], m_offset[0], m_power[0], m_slope[0]); + p.out[1] = fac_m * in_color[1] + + fac * colorbalance_cdl(in_color[1], m_offset[1], m_power[1], m_slope[1]); + p.out[2] = fac_m * in_color[2] + + fac * colorbalance_cdl(in_color[2], m_offset[2], m_power[2], m_slope[2]); + p.out[3] = in_color[3]; + } +} + void ColorBalanceASCCDLOperation::deinitExecution() { this->m_inputValueOperation = nullptr; diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h index 5851600190f..d161ea66af2 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h @@ -18,7 +18,7 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedRowOperation.h" namespace blender::compositor { @@ -26,7 +26,7 @@ namespace blender::compositor { * this program converts an input color to an output value. * it assumes we are in sRGB color space. */ -class ColorBalanceASCCDLOperation : public NodeOperation { +class ColorBalanceASCCDLOperation : public MultiThreadedRowOperation { protected: /** * Prefetched reference to the inputProgram @@ -71,6 +71,8 @@ class ColorBalanceASCCDLOperation : public NodeOperation { { copy_v3_v3(this->m_slope, slope); } + + void update_memory_buffer_row(PixelCursor &p) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc index cac16a3f7b0..674cb79a238 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc @@ -46,6 +46,7 @@ ColorBalanceLGGOperation::ColorBalanceLGGOperation() this->m_inputValueOperation = nullptr; this->m_inputColorOperation = nullptr; this->setResolutionInputSocketIndex(1); + flags.can_be_constant = true; } void ColorBalanceLGGOperation::initExecution() @@ -81,6 +82,23 @@ void ColorBalanceLGGOperation::executePixelSampled(float output[4], output[3] = inputColor[3]; } +void ColorBalanceLGGOperation::update_memory_buffer_row(PixelCursor &p) +{ + for (; p.out < p.row_end; p.next()) { + const float *in_factor = p.ins[0]; + const float *in_color = p.ins[1]; + const float fac = MIN2(1.0f, in_factor[0]); + const float fac_m = 1.0f - fac; + p.out[0] = fac_m * in_color[0] + + fac * colorbalance_lgg(in_color[0], m_lift[0], m_gamma_inv[0], m_gain[0]); + p.out[1] = fac_m * in_color[1] + + fac * colorbalance_lgg(in_color[1], m_lift[1], m_gamma_inv[1], m_gain[1]); + p.out[2] = fac_m * in_color[2] + + fac * colorbalance_lgg(in_color[2], m_lift[2], m_gamma_inv[2], m_gain[2]); + p.out[3] = in_color[3]; + } +} + void ColorBalanceLGGOperation::deinitExecution() { this->m_inputValueOperation = nullptr; diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h index 23f70247b66..4bc929ed76c 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h @@ -18,7 +18,7 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedRowOperation.h" namespace blender::compositor { @@ -26,7 +26,7 @@ namespace blender::compositor { * this program converts an input color to an output value. * it assumes we are in sRGB color space. */ -class ColorBalanceLGGOperation : public NodeOperation { +class ColorBalanceLGGOperation : public MultiThreadedRowOperation { protected: /** * Prefetched reference to the inputProgram @@ -71,6 +71,8 @@ class ColorBalanceLGGOperation : public NodeOperation { { copy_v3_v3(this->m_gamma_inv, gamma_inv); } + + void update_memory_buffer_row(PixelCursor &p) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc index 168e9b57eb2..b50145b106d 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc @@ -33,6 +33,7 @@ ColorCorrectionOperation::ColorCorrectionOperation() this->m_redChannelEnabled = true; this->m_greenChannelEnabled = true; this->m_blueChannelEnabled = true; + flags.can_be_constant = true; } void ColorCorrectionOperation::initExecution() { @@ -157,6 +158,86 @@ void ColorCorrectionOperation::executePixelSampled(float output[4], output[3] = inputImageColor[3]; } +void ColorCorrectionOperation::update_memory_buffer_row(PixelCursor &p) +{ + for (; p.out < p.row_end; p.next()) { + const float *in_color = p.ins[0]; + const float *in_mask = p.ins[1]; + + const float level = (in_color[0] + in_color[1] + in_color[2]) / 3.0f; + float level_shadows = 0.0f; + float level_midtones = 0.0f; + float level_highlights = 0.0f; + constexpr float MARGIN = 0.10f; + constexpr float MARGIN_DIV = 0.5f / MARGIN; + if (level < this->m_data->startmidtones - MARGIN) { + level_shadows = 1.0f; + } + else if (level < this->m_data->startmidtones + MARGIN) { + level_midtones = ((level - this->m_data->startmidtones) * MARGIN_DIV) + 0.5f; + level_shadows = 1.0f - level_midtones; + } + else if (level < this->m_data->endmidtones - MARGIN) { + level_midtones = 1.0f; + } + else if (level < this->m_data->endmidtones + MARGIN) { + level_highlights = ((level - this->m_data->endmidtones) * MARGIN_DIV) + 0.5f; + level_midtones = 1.0f - level_highlights; + } + else { + level_highlights = 1.0f; + } + float contrast = this->m_data->master.contrast; + float saturation = this->m_data->master.saturation; + float gamma = this->m_data->master.gamma; + float gain = this->m_data->master.gain; + float lift = this->m_data->master.lift; + contrast *= level_shadows * this->m_data->shadows.contrast + + level_midtones * this->m_data->midtones.contrast + + level_highlights * this->m_data->highlights.contrast; + saturation *= level_shadows * this->m_data->shadows.saturation + + level_midtones * this->m_data->midtones.saturation + + level_highlights * this->m_data->highlights.saturation; + gamma *= level_shadows * this->m_data->shadows.gamma + + level_midtones * this->m_data->midtones.gamma + + level_highlights * this->m_data->highlights.gamma; + gain *= level_shadows * this->m_data->shadows.gain + + level_midtones * this->m_data->midtones.gain + + level_highlights * this->m_data->highlights.gain; + lift += level_shadows * this->m_data->shadows.lift + + level_midtones * this->m_data->midtones.lift + + level_highlights * this->m_data->highlights.lift; + + const float inv_gamma = 1.0f / gamma; + const float luma = IMB_colormanagement_get_luminance(in_color); + + float r = luma + saturation * (in_color[0] - luma); + float g = luma + saturation * (in_color[1] - luma); + float b = luma + saturation * (in_color[2] - luma); + + r = 0.5f + (r - 0.5f) * contrast; + g = 0.5f + (g - 0.5f) * contrast; + b = 0.5f + (b - 0.5f) * contrast; + + /* Check for negative values to avoid nan. */ + r = color_correct_powf_safe(r * gain + lift, inv_gamma, r); + g = color_correct_powf_safe(g * gain + lift, inv_gamma, g); + b = color_correct_powf_safe(b * gain + lift, inv_gamma, b); + + /* Mix with mask. */ + const float value = MIN2(1.0f, in_mask[0]); + const float m_value = 1.0f - value; + r = m_value * in_color[0] + value * r; + g = m_value * in_color[1] + value * g; + b = m_value * in_color[2] + value * b; + + p.out[0] = m_redChannelEnabled ? r : in_color[0]; + p.out[1] = m_greenChannelEnabled ? g : in_color[1]; + p.out[2] = m_blueChannelEnabled ? b : in_color[2]; + p.out[3] = in_color[3]; + } +} + void ColorCorrectionOperation::deinitExecution() { this->m_inputImage = nullptr; diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h index c5826ed0152..32b5e02e77a 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h @@ -18,11 +18,11 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedRowOperation.h" namespace blender::compositor { -class ColorCorrectionOperation : public NodeOperation { +class ColorCorrectionOperation : public MultiThreadedRowOperation { private: /** * Cached reference to the inputProgram @@ -69,6 +69,8 @@ class ColorCorrectionOperation : public NodeOperation { { this->m_blueChannelEnabled = enabled; } + + void update_memory_buffer_row(PixelCursor &p) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorExposureOperation.cc b/source/blender/compositor/operations/COM_ColorExposureOperation.cc index 1512ff87658..228550a31c5 100644 --- a/source/blender/compositor/operations/COM_ColorExposureOperation.cc +++ b/source/blender/compositor/operations/COM_ColorExposureOperation.cc @@ -26,6 +26,7 @@ ExposureOperation::ExposureOperation() this->addInputSocket(DataType::Value); this->addOutputSocket(DataType::Color); this->m_inputProgram = nullptr; + flags.can_be_constant = true; } void ExposureOperation::initExecution() @@ -52,6 +53,19 @@ void ExposureOperation::executePixelSampled(float output[4], output[3] = inputValue[3]; } +void ExposureOperation::update_memory_buffer_row(PixelCursor &p) +{ + for (; p.out < p.row_end; p.next()) { + const float *in_value = p.ins[0]; + const float *in_exposure = p.ins[1]; + const float exposure = pow(2, in_exposure[0]); + p.out[0] = in_value[0] * exposure; + p.out[1] = in_value[1] * exposure; + p.out[2] = in_value[2] * exposure; + p.out[3] = in_value[3]; + } +} + void ExposureOperation::deinitExecution() { this->m_inputProgram = nullptr; diff --git a/source/blender/compositor/operations/COM_ColorExposureOperation.h b/source/blender/compositor/operations/COM_ColorExposureOperation.h index 0cfaa059e41..1eb790e8d52 100644 --- a/source/blender/compositor/operations/COM_ColorExposureOperation.h +++ b/source/blender/compositor/operations/COM_ColorExposureOperation.h @@ -18,11 +18,11 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedRowOperation.h" namespace blender::compositor { -class ExposureOperation : public NodeOperation { +class ExposureOperation : public MultiThreadedRowOperation { private: /** * Cached reference to the inputProgram @@ -47,6 +47,8 @@ class ExposureOperation : public NodeOperation { * Deinitialize the execution */ void deinitExecution() override; + + void update_memory_buffer_row(PixelCursor &p) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConstantOperation.cc b/source/blender/compositor/operations/COM_ConstantOperation.cc new file mode 100644 index 00000000000..f905edbde76 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConstantOperation.cc @@ -0,0 +1,28 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#include "COM_ConstantOperation.h" + +namespace blender::compositor { + +ConstantOperation::ConstantOperation() +{ + flags.is_constant_operation = true; +} + +} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConstantOperation.h b/source/blender/compositor/operations/COM_ConstantOperation.h new file mode 100644 index 00000000000..2709efeebd8 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConstantOperation.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#pragma once + +#include "COM_NodeOperation.h" + +namespace blender::compositor { + +/** + * Base class for primitive constant operations (Color/Vector/Value). The rest of operations that + * can be constant are evaluated into primitives during constant folding. + */ +class ConstantOperation : public NodeOperation { + public: + ConstantOperation(); + + virtual const float *get_constant_elem() = 0; +}; + +} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GammaOperation.cc b/source/blender/compositor/operations/COM_GammaOperation.cc index 343e335070a..396d3942b06 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.cc +++ b/source/blender/compositor/operations/COM_GammaOperation.cc @@ -28,6 +28,7 @@ GammaOperation::GammaOperation() this->addOutputSocket(DataType::Color); this->m_inputProgram = nullptr; this->m_inputGammaProgram = nullptr; + flags.can_be_constant = true; } void GammaOperation::initExecution() { @@ -51,6 +52,20 @@ void GammaOperation::executePixelSampled(float output[4], float x, float y, Pixe output[3] = inputValue[3]; } +void GammaOperation::update_memory_buffer_row(PixelCursor &p) +{ + for (; p.out < p.row_end; p.next()) { + const float *in_value = p.ins[0]; + const float *in_gamma = p.ins[1]; + const float gamma = in_gamma[0]; + /* Check for negative to avoid nan's. */ + p.out[0] = in_value[0] > 0.0f ? powf(in_value[0], gamma) : in_value[0]; + p.out[1] = in_value[1] > 0.0f ? powf(in_value[1], gamma) : in_value[1]; + p.out[2] = in_value[2] > 0.0f ? powf(in_value[2], gamma) : in_value[2]; + p.out[3] = in_value[3]; + } +} + void GammaOperation::deinitExecution() { this->m_inputProgram = nullptr; diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h index 034046106d6..713d3d8484f 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.h +++ b/source/blender/compositor/operations/COM_GammaOperation.h @@ -18,11 +18,11 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedRowOperation.h" namespace blender::compositor { -class GammaOperation : public NodeOperation { +class GammaOperation : public MultiThreadedRowOperation { private: /** * Cached reference to the inputProgram @@ -47,6 +47,8 @@ class GammaOperation : public NodeOperation { * Deinitialize the execution */ void deinitExecution() override; + + void update_memory_buffer_row(PixelCursor &p) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cc b/source/blender/compositor/operations/COM_IDMaskOperation.cc index 38f8b7e075f..bb11ac8b1be 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.cc +++ b/source/blender/compositor/operations/COM_IDMaskOperation.cc @@ -25,6 +25,7 @@ IDMaskOperation::IDMaskOperation() this->addInputSocket(DataType::Value); this->addOutputSocket(DataType::Value); this->flags.complex = true; + flags.can_be_constant = true; } void *IDMaskOperation::initializeTileData(rcti *rect) diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cc b/source/blender/compositor/operations/COM_NormalizeOperation.cc index faacb429f71..f93afcaab95 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cc +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cc @@ -36,7 +36,7 @@ void NormalizeOperation::initExecution() void NormalizeOperation::executePixel(float output[4], int x, int y, void *data) { - /* using generic two floats struct to store x: min y: mult */ + /* using generic two floats struct to store `x: min`, `y: multiply` */ NodeTwoFloats *minmult = (NodeTwoFloats *)data; this->m_imageReader->read(output, x, y, nullptr); @@ -89,7 +89,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect) lockMutex(); if (this->m_cachedInstance == nullptr) { MemoryBuffer *tile = (MemoryBuffer *)this->m_imageReader->initializeTileData(rect); - /* using generic two floats struct to store x: min y: mult */ + /* using generic two floats struct to store `x: min`, `y: multiply`. */ NodeTwoFloats *minmult = new NodeTwoFloats(); float *buffer = tile->getBuffer(); diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h index 93d4a0fc67d..c89ba372189 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.h +++ b/source/blender/compositor/operations/COM_NormalizeOperation.h @@ -36,7 +36,7 @@ class NormalizeOperation : public NodeOperation { /** * \brief temporarily cache of the execution storage - * it stores x->min and y->mult + * it stores `x->min` and `y->multiply`. */ NodeTwoFloats *m_cachedInstance; diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc index 9dde73269fc..c3647a39909 100644 --- a/source/blender/compositor/operations/COM_SMAAOperation.cc +++ b/source/blender/compositor/operations/COM_SMAAOperation.cc @@ -36,12 +36,12 @@ namespace blender::compositor { * * http://www.iryoku.com/smaa/ * - * This file is based on smaa-cpp: + * This file is based on SMAA-CPP: * * https://github.com/iRi-E/smaa-cpp * * Currently only SMAA 1x mode is provided, so the operation will be done - * with no spatial multisampling nor temporal supersampling. + * with no spatial multi-sampling nor temporal super-sampling. * * NOTE: This program assumes the screen coordinates are DirectX style, so * the vertical direction is upside-down. "top" and "bottom" actually mean diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cc b/source/blender/compositor/operations/COM_SetColorOperation.cc index 79dee33e266..bfe735aab15 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.cc +++ b/source/blender/compositor/operations/COM_SetColorOperation.cc @@ -44,8 +44,7 @@ void SetColorOperation::determineResolution(unsigned int resolution[2], void SetColorOperation::update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs), - ExecutionSystem &UNUSED(exec_system)) + Span<MemoryBuffer *> UNUSED(inputs)) { BLI_assert(output->is_a_single_elem()); float *out_elem = output->get_elem(area.xmin, area.ymin); diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h index 2e22ef60ba4..f4c0948ee1b 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.h +++ b/source/blender/compositor/operations/COM_SetColorOperation.h @@ -18,7 +18,7 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_ConstantOperation.h" namespace blender::compositor { @@ -26,7 +26,7 @@ namespace blender::compositor { * this program converts an input color to an output value. * it assumes we are in sRGB color space. */ -class SetColorOperation : public NodeOperation { +class SetColorOperation : public ConstantOperation { private: float m_color[4]; @@ -36,6 +36,11 @@ class SetColorOperation : public NodeOperation { */ SetColorOperation(); + const float *get_constant_elem() override + { + return m_color; + } + float getChannel1() { return this->m_color[0]; @@ -83,8 +88,7 @@ class SetColorOperation : public NodeOperation { void update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> inputs, - ExecutionSystem &exec_system) override; + Span<MemoryBuffer *> inputs) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cc b/source/blender/compositor/operations/COM_SetValueOperation.cc index 359647c8fe3..c12fb106afd 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.cc +++ b/source/blender/compositor/operations/COM_SetValueOperation.cc @@ -44,8 +44,7 @@ void SetValueOperation::determineResolution(unsigned int resolution[2], void SetValueOperation::update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs), - ExecutionSystem &UNUSED(exec_system)) + Span<MemoryBuffer *> UNUSED(inputs)) { BLI_assert(output->is_a_single_elem()); float *out_elem = output->get_elem(area.xmin, area.ymin); diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h index acde5aa03b7..f18d44d9554 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.h +++ b/source/blender/compositor/operations/COM_SetValueOperation.h @@ -18,7 +18,7 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_ConstantOperation.h" namespace blender::compositor { @@ -26,7 +26,7 @@ namespace blender::compositor { * this program converts an input color to an output value. * it assumes we are in sRGB color space. */ -class SetValueOperation : public NodeOperation { +class SetValueOperation : public ConstantOperation { private: float m_value; @@ -36,6 +36,11 @@ class SetValueOperation : public NodeOperation { */ SetValueOperation(); + const float *get_constant_elem() override + { + return &m_value; + } + float getValue() { return this->m_value; @@ -53,8 +58,7 @@ class SetValueOperation : public NodeOperation { unsigned int preferredResolution[2]) override; void update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> inputs, - ExecutionSystem &exec_system) override; + Span<MemoryBuffer *> inputs) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cc b/source/blender/compositor/operations/COM_SetVectorOperation.cc index 7152d5e61d4..7b8cf44048c 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cc +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cc @@ -32,9 +32,9 @@ void SetVectorOperation::executePixelSampled(float output[4], float /*y*/, PixelSampler /*sampler*/) { - output[0] = this->m_x; - output[1] = this->m_y; - output[2] = this->m_z; + output[0] = vector_.x; + output[1] = vector_.y; + output[2] = vector_.z; } void SetVectorOperation::determineResolution(unsigned int resolution[2], diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h index b444339fcb2..41fd06659d6 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.h +++ b/source/blender/compositor/operations/COM_SetVectorOperation.h @@ -18,7 +18,7 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_ConstantOperation.h" namespace blender::compositor { @@ -26,12 +26,14 @@ namespace blender::compositor { * this program converts an input color to an output value. * it assumes we are in sRGB color space. */ -class SetVectorOperation : public NodeOperation { +class SetVectorOperation : public ConstantOperation { private: - float m_x; - float m_y; - float m_z; - float m_w; + struct { + float x; + float y; + float z; + float w; + } vector_; public: /** @@ -39,37 +41,42 @@ class SetVectorOperation : public NodeOperation { */ SetVectorOperation(); + const float *get_constant_elem() override + { + return reinterpret_cast<float *>(&vector_); + } + float getX() { - return this->m_x; + return vector_.x; } void setX(float value) { - this->m_x = value; + vector_.x = value; } float getY() { - return this->m_y; + return vector_.y; } void setY(float value) { - this->m_y = value; + vector_.y = value; } float getZ() { - return this->m_z; + return vector_.z; } void setZ(float value) { - this->m_z = value; + vector_.z = value; } float getW() { - return this->m_w; + return vector_.w; } void setW(float value) { - this->m_w = value; + vector_.w = value; } /** diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cc b/source/blender/compositor/operations/COM_VectorBlurOperation.cc index 5adcc4fdd4c..b5b5d426338 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cc +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cc @@ -432,7 +432,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove) } } - /* 2: evaluate horizontal scanlines and calculate alphas */ + /* 2: evaluate horizontal scan-lines and calculate alphas. */ row1 = rectmove; for (y = 0; y < ysize; y++) { row1++; @@ -463,7 +463,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove) } } - /* 3: evaluate vertical scanlines and calculate alphas */ + /* 3: evaluate vertical scan-lines and calculate alphas */ /* use for reading a copy of the original tagged buffer */ for (x = 0; x < xsize; x++) { row1 = rectmove + x + xsize; diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 27441c9a7ae..749b1bba871 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -159,7 +159,7 @@ void DEG_ids_restore_recalc(Depsgraph *depsgraph); /* Graph Evaluation ----------------------------- */ /* Frame changed recalculation entry point. */ -void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime); +void DEG_evaluate_on_framechange(Depsgraph *graph, float frame); /* Data changed recalculation entry point. */ void DEG_evaluate_on_refresh(Depsgraph *graph); diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 1c87fd263da..17f5ca0db79 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -95,7 +95,7 @@ struct ViewLayer *DEG_get_evaluated_view_layer(const struct Depsgraph *graph); /* Get evaluated version of object for given original one. */ struct Object *DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object); -/* Get evaluated version of given ID datablock. */ +/* Get evaluated version of given ID data-block. */ struct ID *DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id); /* Get evaluated version of data pointed to by RNA pointer */ @@ -106,7 +106,7 @@ void DEG_get_evaluated_rna_pointer(const struct Depsgraph *depsgraph, /* Get original version of object for given evaluated one. */ struct Object *DEG_get_original_object(struct Object *object); -/* Get original version of given evaluated ID datablock. */ +/* Get original version of given evaluated ID data-block. */ struct ID *DEG_get_original_id(struct ID *id); /* Check whether given ID is an original, @@ -122,7 +122,7 @@ bool DEG_is_original_object(const struct Object *object); bool DEG_is_evaluated_id(const struct ID *id); bool DEG_is_evaluated_object(const struct Object *object); -/* Check whether depsgraph os fully evaluated. This includes the following checks: +/* Check whether depsgraph is fully evaluated. This includes the following checks: * - Relations are up-to-date. * - Nothing is tagged for update. */ bool DEG_is_fully_evaluated(const struct Depsgraph *depsgraph); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 56168739fae..c8179fb1eff 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1495,7 +1495,7 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob add_operation_node( &object->id, NodeType::BATCH_CACHE, - OperationCode::GEOMETRY_SELECT_UPDATE, + OperationCode::BATCH_UPDATE_SELECT, [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); }); } @@ -1516,33 +1516,37 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool if (key) { build_shapekeys(key); } - /* Nodes for result of obdata's evaluation, and geometry - * evaluation on object. */ + + /* Geometry evaluation. */ + /* Entry operation, takes care of initialization, and some other + * relations which needs to be run prior to actual geometry evaluation. */ + op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); + op_node->set_as_entry(); + + add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DEFORM); + const ID_Type id_type = GS(obdata->name); switch (id_type) { case ID_ME: { - op_node = add_operation_node(obdata, - NodeType::GEOMETRY, - OperationCode::GEOMETRY_EVAL, - [obdata_cow](::Depsgraph *depsgraph) { - BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow); - }); - op_node->set_as_entry(); + add_operation_node(obdata, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_EVAL, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow); + }); break; } case ID_MB: { - op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); - op_node->set_as_entry(); + add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); break; } case ID_CU: { - op_node = add_operation_node(obdata, - NodeType::GEOMETRY, - OperationCode::GEOMETRY_EVAL, - [obdata_cow](::Depsgraph *depsgraph) { - BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow); - }); - op_node->set_as_entry(); + add_operation_node(obdata, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_EVAL, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow); + }); /* Make sure objects used for bevel.taper are in the graph. * NOTE: This objects might be not linked to the scene. */ Curve *cu = (Curve *)obdata; @@ -1558,47 +1562,41 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool break; } case ID_LT: { - op_node = add_operation_node(obdata, - NodeType::GEOMETRY, - OperationCode::GEOMETRY_EVAL, - [obdata_cow](::Depsgraph *depsgraph) { - BKE_lattice_eval_geometry(depsgraph, (Lattice *)obdata_cow); - }); - op_node->set_as_entry(); + add_operation_node(obdata, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_EVAL, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_lattice_eval_geometry(depsgraph, (Lattice *)obdata_cow); + }); break; } case ID_GD: { /* GPencil evaluation operations. */ - op_node = add_operation_node(obdata, - NodeType::GEOMETRY, - OperationCode::GEOMETRY_EVAL, - [obdata_cow](::Depsgraph *depsgraph) { - BKE_gpencil_frame_active_set(depsgraph, - (bGPdata *)obdata_cow); - }); - op_node->set_as_entry(); + add_operation_node(obdata, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_EVAL, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_gpencil_frame_active_set(depsgraph, (bGPdata *)obdata_cow); + }); break; } case ID_HA: { - op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); - op_node->set_as_entry(); + add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); break; } case ID_PT: { - op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); - op_node->set_as_entry(); + add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); break; } case ID_VO: { /* Volume frame update. */ - op_node = add_operation_node(obdata, - NodeType::GEOMETRY, - OperationCode::GEOMETRY_EVAL, - [obdata_cow](::Depsgraph *depsgraph) { - BKE_volume_eval_geometry(depsgraph, (Volume *)obdata_cow); - }); - op_node->set_as_entry(); + add_operation_node(obdata, + NodeType::GEOMETRY, + OperationCode::GEOMETRY_EVAL, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_volume_eval_geometry(depsgraph, (Volume *)obdata_cow); + }); break; } default: @@ -1612,10 +1610,22 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool /* Batch cache. */ add_operation_node(obdata, NodeType::BATCH_CACHE, - OperationCode::GEOMETRY_SELECT_UPDATE, + OperationCode::BATCH_UPDATE_SELECT, [obdata_cow](::Depsgraph *depsgraph) { BKE_object_data_select_update(depsgraph, obdata_cow); }); + add_operation_node(obdata, + NodeType::BATCH_CACHE, + OperationCode::BATCH_UPDATE_DEFORM, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_object_data_eval_batch_cache_deform_tag(depsgraph, obdata_cow); + }); + add_operation_node(obdata, + NodeType::BATCH_CACHE, + OperationCode::BATCH_UPDATE_ALL, + [obdata_cow](::Depsgraph *depsgraph) { + BKE_object_data_eval_batch_cache_dirty_tag(depsgraph, obdata_cow); + }); } void DepsgraphNodeBuilder::build_armature(bArmature *armature) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 151e0d844b6..3b2dd44af0d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -289,7 +289,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { * setting the current state. */ Collection *collection_; /* Accumulated flag over the hierarchy of currently building collections. - * Denotes whether all the hierarchy from parent of collection_ to the + * Denotes whether all the hierarchy from parent of `collection_` to the * very root is visible (aka not restricted.). */ bool is_parent_collection_visible_; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index c269ad16824..7486f798fdb 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -647,7 +647,7 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll /* Only create geometry relations to child objects, if they have a geometry component. */ OperationKey object_geometry_key{ - &cob->ob->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL}; + &cob->ob->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT}; if (find_node(object_geometry_key) != nullptr) { add_relation(object_geometry_key, collection_geometry_key, "Collection Geometry"); } @@ -1098,7 +1098,8 @@ void DepsgraphRelationBuilder::build_object_pointcache(Object *object) } else { flag = FLAG_GEOMETRY; - OperationKey geometry_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + OperationKey geometry_key( + &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); add_relation(point_cache_key, geometry_key, "Point Cache -> Geometry"); } BLI_assert(flag != -1); @@ -1868,7 +1869,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) void DepsgraphRelationBuilder::build_particle_systems(Object *object) { TimeSourceKey time_src_key; - OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + OperationKey obdata_ubereval_key( + &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); OperationKey eval_init_key( &object->id, NodeType::PARTICLE_SYSTEM, OperationCode::PARTICLE_SYSTEM_INIT); OperationKey eval_done_key( @@ -2016,7 +2018,8 @@ void DepsgraphRelationBuilder::build_particle_system_visualization_object(Object { OperationKey psys_key( &object->id, NodeType::PARTICLE_SYSTEM, OperationCode::PARTICLE_SYSTEM_EVAL, psys->name); - OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + OperationKey obdata_ubereval_key( + &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); ComponentKey dup_ob_key(&draw_object->id, NodeType::TRANSFORM); add_relation(dup_ob_key, psys_key, "Particle Object Visualization"); if (draw_object->type == OB_MBALL) { @@ -2073,15 +2076,15 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) /* Get nodes for result of obdata's evaluation, and geometry evaluation * on object. */ ComponentKey obdata_geom_key(obdata, NodeType::GEOMETRY); - ComponentKey geom_key(&object->id, NodeType::GEOMETRY); - /* Link components to each other. */ - add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data"); OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + /* Link components to each other. */ + add_relation(obdata_geom_key, obdata_ubereval_key, "Object Geometry Base Data"); + /* Special case: modifiers evaluation queries scene for various things like * data mask to be used. We add relation here to ensure object is never * evaluated prior to Scene's CoW is ready. */ OperationKey scene_key(&scene_->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL); - Relation *rel = add_relation(scene_key, obdata_ubereval_key, "CoW Relation"); + Relation *rel = add_relation(scene_key, geom_init_key, "CoW Relation"); rel->flag |= RELATION_FLAG_NO_FLUSH; /* Modifiers */ if (object->modifiers.first != nullptr) { @@ -2091,13 +2094,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); if (mti->updateDepsgraph) { - DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); + DepsNodeHandle handle = create_node_handle(geom_init_key); ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle); mti->updateDepsgraph(md, &ctx); } if (BKE_object_modifier_use_time(object, md)) { TimeSourceKey time_src_key; - add_relation(time_src_key, obdata_ubereval_key, "Time Source"); + add_relation(time_src_key, geom_init_key, "Time Source"); } } } @@ -2110,13 +2113,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info( (GpencilModifierType)md->type); if (mti->updateDepsgraph) { - DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); + DepsNodeHandle handle = create_node_handle(geom_init_key); ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle); mti->updateDepsgraph(md, &ctx, graph_->mode); } if (BKE_object_modifier_gpencil_use_time(object, md)) { TimeSourceKey time_src_key; - add_relation(time_src_key, obdata_ubereval_key, "Time Source"); + add_relation(time_src_key, geom_init_key, "Time Source"); } } } @@ -2128,13 +2131,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) LISTBASE_FOREACH (ShaderFxData *, fx, &object->shader_fx) { const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info((ShaderFxType)fx->type); if (fxi->updateDepsgraph) { - DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); + DepsNodeHandle handle = create_node_handle(geom_init_key); ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle); fxi->updateDepsgraph(fx, &ctx); } if (BKE_object_shaderfx_use_time(object, fx)) { TimeSourceKey time_src_key; - add_relation(time_src_key, obdata_ubereval_key, "Time Source"); + add_relation(time_src_key, geom_init_key, "Time Source"); } } } @@ -2160,6 +2163,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) add_relation(mom_transform_key, mom_geom_key, "Metaball Motherball Transform -> Geometry"); } else { + ComponentKey geom_key(&object->id, NodeType::GEOMETRY); ComponentKey transform_key(&object->id, NodeType::TRANSFORM); add_relation(geom_key, mom_geom_key, "Metaball Motherball"); add_relation(transform_key, mom_geom_key, "Metaball Motherball"); @@ -2174,9 +2178,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) * Ideally we need to get rid of this relation. */ if (object_particles_depends_on_time(object)) { TimeSourceKey time_key; - OperationKey obdata_ubereval_key( - &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); - add_relation(time_key, obdata_ubereval_key, "Legacy particle time"); + add_relation(time_key, geom_init_key, "Legacy particle time"); } /* Object data data-block. */ build_object_data_geometry_datablock((ID *)object->data); @@ -2198,12 +2200,33 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) add_relation(final_geometry_key, synchronize_key, "Synchronize to Original"); /* Batch cache. */ OperationKey object_data_select_key( - obdata, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE); + obdata, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_SELECT); OperationKey object_select_key( - &object->id, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE); + &object->id, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_SELECT); + add_relation(object_data_select_key, object_select_key, "Data Selection -> Object Selection"); + add_relation(final_geometry_key, + object_select_key, + "Object Geometry -> Select Update", + RELATION_FLAG_NO_FLUSH); + + OperationKey object_data_geom_deform_key( + obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DEFORM); + OperationKey object_data_geom_init_key( + obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); + + OperationKey object_data_batch_deform_key( + obdata, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_DEFORM); + OperationKey object_data_batch_all_key( + obdata, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_ALL); + + add_relation(geom_init_key, object_data_batch_all_key, "Object Geometry -> Batch Update All"); + add_relation( - geom_key, object_select_key, "Object Geometry -> Select Update", RELATION_FLAG_NO_FLUSH); + object_data_geom_init_key, object_data_batch_all_key, "Data Init -> Batch Update All"); + add_relation(object_data_geom_deform_key, + object_data_batch_deform_key, + "Data Deform -> Batch Update Deform"); } void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata) @@ -2221,8 +2244,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata) build_shapekeys(key); } /* Link object data evaluation node to exit operation. */ + OperationKey obdata_geom_deform_key( + obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DEFORM); + OperationKey obdata_geom_init_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); OperationKey obdata_geom_eval_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); OperationKey obdata_geom_done_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE); + add_relation(obdata_geom_init_key, obdata_geom_eval_key, "ObData Init -> Geom Eval"); + add_relation(obdata_geom_deform_key, obdata_geom_eval_key, "ObData Deform -> Geom Eval"); add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done"); /* Type-specific links. */ const ID_Type id_type = GS(obdata->name); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 54c51adec66..2ae29dea213 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -180,7 +180,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.operation_name = ""; node_identifier.operation_name_tag = -1; /* Handling of commonly known scenarios. */ - if (prop != nullptr && RNA_property_is_idprop(prop)) { + if (prop != nullptr && RNA_property_is_idprop(prop) && + !RNA_struct_is_a(ptr->type, &RNA_Modifier)) { node_identifier.type = NodeType::PARAMETERS; node_identifier.operation_code = OperationCode::ID_PROPERTY; node_identifier.operation_name = RNA_property_identifier( diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 6fe7d5f5d8b..076e15a3175 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -68,7 +68,8 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati scene(scene), view_layer(view_layer), mode(mode), - ctime(BKE_scene_frame_get(scene)), + frame(BKE_scene_frame_get(scene)), + ctime(BKE_scene_ctime_get(scene)), scene_cow(nullptr), is_active(false), is_evaluating(false), diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index ff536c19c05..913b61ca563 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -140,7 +140,9 @@ struct Depsgraph { ViewLayer *view_layer; eEvaluationMode mode; - /* Time at which dependency graph is being or was last evaluated. */ + /* Time at which dependency graph is being or was last evaluated. + * frame is the value before, and ctime the value after time remapping. */ + float frame; float ctime; /* Evaluated version of datablocks we access a lot. diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 1ad3fdbc9da..cc7ce871419 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -51,7 +51,7 @@ static void deg_flush_updates_and_refresh(deg::Depsgraph *deg_graph) { /* Update the time on the cow scene. */ if (deg_graph->scene_cow) { - BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); + BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->frame); } deg::deg_graph_flush_updates(deg_graph); @@ -63,10 +63,12 @@ void DEG_evaluate_on_refresh(Depsgraph *graph) { deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); const Scene *scene = DEG_get_input_scene(graph); - const float ctime = BKE_scene_frame_get(scene); + const float frame = BKE_scene_frame_get(scene); + const float ctime = BKE_scene_ctime_get(scene); - if (ctime != deg_graph->ctime) { + if (deg_graph->frame != frame || ctime != deg_graph->ctime) { deg_graph->tag_time_source(); + deg_graph->frame = frame; deg_graph->ctime = ctime; } @@ -74,10 +76,13 @@ void DEG_evaluate_on_refresh(Depsgraph *graph) } /* Frame-change happened for root scene that graph belongs to. */ -void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime) +void DEG_evaluate_on_framechange(Depsgraph *graph, float frame) { deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); + const Scene *scene = DEG_get_input_scene(graph); + deg_graph->tag_time_source(); - deg_graph->ctime = ctime; + deg_graph->frame = frame; + deg_graph->ctime = BKE_scene_frame_to_ctime(scene, frame); deg_flush_updates_and_refresh(deg_graph); } diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index b00cae87311..e879e8d0f23 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -117,7 +117,7 @@ void depsgraph_select_tag_to_component_opcode(const ID *id, } else if (is_selectable_data_id_type(id_type)) { *component_type = NodeType::BATCH_CACHE; - *operation_code = OperationCode::GEOMETRY_SELECT_UPDATE; + *operation_code = OperationCode::BATCH_UPDATE_SELECT; } else { *component_type = NodeType::COPY_ON_WRITE; @@ -168,6 +168,11 @@ void depsgraph_tag_to_component_opcode(const ID *id, break; case ID_RECALC_GEOMETRY: depsgraph_geometry_tag_to_component(id, component_type); + *operation_code = OperationCode::GEOMETRY_EVAL_INIT; + break; + case ID_RECALC_GEOMETRY_DEFORM: + depsgraph_geometry_tag_to_component(id, component_type); + *operation_code = OperationCode::GEOMETRY_EVAL_DEFORM; break; case ID_RECALC_ANIMATION: *component_type = NodeType::ANIMATION; @@ -708,6 +713,8 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag) return "GEOMETRY"; case ID_RECALC_GEOMETRY_ALL_MODES: return "GEOMETRY_ALL_MODES"; + case ID_RECALC_GEOMETRY_DEFORM: + return "GEOMETRY_DEFORM"; case ID_RECALC_ANIMATION: return "ANIMATION"; case ID_RECALC_PSYS_REDO: diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 1b24e2b7ad2..2cbb0b52e34 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -144,7 +144,10 @@ inline void flush_handle_component_node(IDNode *id_node, * special component where we don't want all operations to be tagged. * * TODO(sergey): Make this a more generic solution. */ - if (!ELEM(comp_node->type, NodeType::PARTICLE_SETTINGS, NodeType::PARTICLE_SYSTEM)) { + if (!ELEM(comp_node->type, + NodeType::PARTICLE_SETTINGS, + NodeType::PARTICLE_SYSTEM, + NodeType::BATCH_CACHE)) { for (OperationNode *op : comp_node->operations) { op->flag |= DEPSOP_FLAG_NEEDS_UPDATE; } diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 7e57467f905..62a3d65d1f4 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -98,6 +98,8 @@ const char *operationCodeAsString(OperationCode opcode) /* Geometry. */ case OperationCode::GEOMETRY_EVAL_INIT: return "GEOMETRY_EVAL_INIT"; + case OperationCode::GEOMETRY_EVAL_DEFORM: + return "GEOMETRY_EVAL_DEFORM"; case OperationCode::GEOMETRY_EVAL: return "GEOMETRY_EVAL"; case OperationCode::GEOMETRY_EVAL_DONE: @@ -160,8 +162,12 @@ const char *operationCodeAsString(OperationCode opcode) case OperationCode::FILE_CACHE_UPDATE: return "FILE_CACHE_UPDATE"; /* Batch cache. */ - case OperationCode::GEOMETRY_SELECT_UPDATE: - return "GEOMETRY_SELECT_UPDATE"; + case OperationCode::BATCH_UPDATE_SELECT: + return "BATCH_UPDATE_SELECT"; + case OperationCode::BATCH_UPDATE_DEFORM: + return "BATCH_UPDATE_DEFORM"; + case OperationCode::BATCH_UPDATE_ALL: + return "BATCH_UPDATE_ALL"; /* Masks. */ case OperationCode::MASK_ANIMATION: return "MASK_ANIMATION"; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index a17186da941..b0130d03c69 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -100,7 +100,11 @@ enum class OperationCode { /* Initialize evaluation of the geometry. Is an entry operation of geometry * component. */ GEOMETRY_EVAL_INIT, - /* Evaluate the whole geometry, including modifiers. */ + /* Evaluate the geometry, including modifiers, and update only batches that + * are affected by deform operations. */ + GEOMETRY_EVAL_DEFORM, + /* Evaluate the geometry, including modifiers, but don't update the batch + * cache. */ GEOMETRY_EVAL, /* Evaluation of geometry is completely done. */ GEOMETRY_EVAL_DONE, @@ -178,7 +182,9 @@ enum class OperationCode { WORLD_UPDATE, /* Batch caches. -------------------------------------------------------- */ - GEOMETRY_SELECT_UPDATE, + BATCH_UPDATE_SELECT, + BATCH_UPDATE_DEFORM, + BATCH_UPDATE_ALL, /* Masks. --------------------------------------------------------------- */ MASK_ANIMATION, diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 1227f4db8e4..ad154704d2c 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -51,14 +51,14 @@ set(INC set(SRC intern/draw_cache.c + intern/draw_cache_extract_mesh.cc intern/draw_cache_extract_mesh_extractors.c intern/draw_cache_extract_mesh_render_data.c - intern/draw_cache_extract_mesh.cc intern/mesh_extractors/extract_mesh_ibo_edituv.cc intern/mesh_extractors/extract_mesh_ibo_fdots.cc + intern/mesh_extractors/extract_mesh_ibo_lines.cc intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc - intern/mesh_extractors/extract_mesh_ibo_lines.cc intern/mesh_extractors/extract_mesh_ibo_points.cc intern/mesh_extractors/extract_mesh_ibo_tris.cc intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc @@ -205,8 +205,8 @@ set(SRC intern/draw_manager_profiling.h intern/draw_manager_testing.h intern/draw_manager_text.h - intern/draw_view.h intern/draw_shader.h + intern/draw_view.h intern/smaa_textures.h engines/basic/basic_engine.h engines/eevee/eevee_engine.h @@ -515,6 +515,8 @@ if(WITH_GTESTS) set(TEST_SRC tests/draw_testing.cc tests/shaders_test.cc + + tests/draw_testing.hh ) set(TEST_INC "../../../intern/ghost/" diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index a922ec7cd7d..f51b4fa0127 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -680,7 +680,7 @@ typedef struct EEVEE_GeometryMotionData { int use_deform; struct GPUBatch *batch; /* Batch for time = t. */ - struct GPUVertBuf *vbo[2]; /* Vbo for time = t +/- step. */ + struct GPUVertBuf *vbo[2]; /* VBO for time = t +/- step. */ } EEVEE_GeometryMotionData; /* ************ EFFECTS DATA ************* */ diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index 23893d79090..b7bcd127859 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -144,7 +144,7 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), /* Clear texture. * Due to the late initialization of the SSS it can happen that the `taa_current_sample` is * already higher than one. This is noticeable when loading a file that has the diffuse light - * pass in look dev mode active. `texture_created` will make sure that newly created textures + * pass in look-dev mode active. `texture_created` will make sure that newly created textures * are cleared. */ if (effects->taa_current_sample == 1 || texture_created) { const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 06dd8a64485..84626eac4cf 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -278,7 +278,7 @@ vec3 probe_evaluate_grid(GridData gd, vec3 P, vec3 N, vec3 localpos) float ws_dist_point_to_cell = length(ws_point_to_cell); vec3 ws_light = ws_point_to_cell / ws_dist_point_to_cell; - /* Smooth backface test */ + /* Smooth back-face test. */ float weight = saturate(dot(ws_light, N)); /* Precomputed visibility */ diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index 90c5f1b95a0..73c4b521b05 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -101,7 +101,7 @@ struct RayTraceParameters { }; /* Returns true on hit. */ -/* TODO: fclem remove the backface check and do it the SSR resolve code. */ +/* TODO(fclem): remove the back-face check and do it the SSR resolve code. */ bool raytrace(Ray ray, RayTraceParameters params, const bool discard_backface, @@ -151,7 +151,7 @@ bool raytrace(Ray ray, /* ... and above it with the added thickness. */ hit = hit && (delta > ss_p.z - ss_p.w || abs(delta) < abs(ssray.direction.z * stride * 2.0)); } - /* Discard backface hits. */ + /* Discard back-face hits. */ hit = hit && !(discard_backface && prev_delta < 0.0); /* Reject hit if background. */ hit = hit && (depth_sample != 1.0); diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index d89cadaa797..d3a0c40fae5 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -640,13 +640,13 @@ void GPENCIL_cache_populate(void *ved, Object *ob) } } - BKE_gpencil_visible_stroke_iter(is_final_render ? pd->view_layer : NULL, - ob, - gpencil_layer_cache_populate, - gpencil_stroke_cache_populate, - &iter, - do_onion, - pd->cfra); + BKE_gpencil_visible_stroke_advanced_iter(is_final_render ? pd->view_layer : NULL, + ob, + gpencil_layer_cache_populate, + gpencil_stroke_cache_populate, + &iter, + do_onion, + pd->cfra); gpencil_drawcall_flush(&iter); diff --git a/source/blender/draw/engines/image/image_engine.c b/source/blender/draw/engines/image/image_engine.c index 2522a445d8e..b6fd73e76d1 100644 --- a/source/blender/draw/engines/image/image_engine.c +++ b/source/blender/draw/engines/image/image_engine.c @@ -31,6 +31,7 @@ #include "DNA_camera_types.h" #include "DNA_screen_types.h" +#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "ED_image.h" @@ -222,19 +223,30 @@ static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser copy_v4_fl4(shuffle, 1.0f, 0.0f, 0.0f, 0.0f); } else if ((sima_flag & SI_SHOW_R) != 0) { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA | IMAGE_DRAW_FLAG_SHUFFLING; + draw_flags |= IMAGE_DRAW_FLAG_SHUFFLING; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } copy_v4_fl4(shuffle, 1.0f, 0.0f, 0.0f, 0.0f); } else if ((sima_flag & SI_SHOW_G) != 0) { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA | IMAGE_DRAW_FLAG_SHUFFLING; + draw_flags |= IMAGE_DRAW_FLAG_SHUFFLING; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } copy_v4_fl4(shuffle, 0.0f, 1.0f, 0.0f, 0.0f); } else if ((sima_flag & SI_SHOW_B) != 0) { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA | IMAGE_DRAW_FLAG_SHUFFLING; + draw_flags |= IMAGE_DRAW_FLAG_SHUFFLING; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } copy_v4_fl4(shuffle, 0.0f, 0.0f, 1.0f, 0.0f); } else /* RGB */ { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } } } if (space_type == SPACE_NODE) { @@ -248,19 +260,30 @@ static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser copy_v4_fl4(shuffle, 0.0f, 0.0f, 0.0f, 1.0f); } else if ((snode->flag & SNODE_SHOW_R) != 0) { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA | IMAGE_DRAW_FLAG_SHUFFLING; + draw_flags |= IMAGE_DRAW_FLAG_SHUFFLING; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } copy_v4_fl4(shuffle, 1.0f, 0.0f, 0.0f, 0.0f); } else if ((snode->flag & SNODE_SHOW_G) != 0) { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA | IMAGE_DRAW_FLAG_SHUFFLING; + draw_flags |= IMAGE_DRAW_FLAG_SHUFFLING; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } copy_v4_fl4(shuffle, 0.0f, 1.0f, 0.0f, 0.0f); } else if ((snode->flag & SNODE_SHOW_B) != 0) { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA | IMAGE_DRAW_FLAG_SHUFFLING; + draw_flags |= IMAGE_DRAW_FLAG_SHUFFLING; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } copy_v4_fl4(shuffle, 0.0f, 0.0f, 1.0f, 0.0f); } else /* RGB */ { - draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + if (IMB_alpha_affects_rgb(ibuf)) { + draw_flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA; + } } } diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.c b/source/blender/draw/engines/overlay/overlay_edit_mesh.c index 7639911286f..a7ed6c777e8 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_mesh.c +++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.c @@ -26,6 +26,7 @@ #include "DNA_mesh_types.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "draw_cache_impl.h" diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.c index 01ab47ac1de..c2b130163e8 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.c +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c @@ -24,6 +24,7 @@ #include "draw_cache_impl.h" #include "draw_manager_text.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_image.h" #include "BKE_layer.h" diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.c index aa26aa47faa..5c03d70d7be 100644 --- a/source/blender/draw/engines/overlay/overlay_gpencil.c +++ b/source/blender/draw/engines/overlay/overlay_gpencil.c @@ -431,7 +431,7 @@ static void OVERLAY_gpencil_color_names(Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); int cfra = DEG_get_ctime(draw_ctx->depsgraph); - BKE_gpencil_visible_stroke_iter( + BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, overlay_gpencil_draw_stroke_color_name, ob, false, cfra); } diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c index b233e084f16..e3f01d968ae 100644 --- a/source/blender/draw/engines/overlay/overlay_outline.c +++ b/source/blender/draw/engines/overlay/overlay_outline.c @@ -263,13 +263,13 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob) gpencil_depth_plane(ob, iter.plane); } - BKE_gpencil_visible_stroke_iter(NULL, - ob, - gpencil_layer_cache_populate, - gpencil_stroke_cache_populate, - &iter, - false, - pd->cfra); + BKE_gpencil_visible_stroke_advanced_iter(NULL, + ob, + gpencil_layer_cache_populate, + gpencil_stroke_cache_populate, + &iter, + false, + pd->cfra); } static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob) diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/armature_shape_solid_frag.glsl index 17e8d0da5d9..26796c82f66 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/armature_shape_solid_frag.glsl @@ -9,8 +9,8 @@ layout(location = 1) out vec4 lineOutput; void main() { - /* Manual backface cullling.. Not ideal for performance - * but needed for view clarity in xray mode and support + /* Manual back-face culling. Not ideal for performance + * but needed for view clarity in X-ray mode and support * for inverted bone matrices. */ if ((inverted == 1) == gl_FrontFacing) { discard; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl index 6e10a656fc1..c5b2ce0fd99 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl @@ -24,7 +24,7 @@ void main() workbench_float_pair_decode(mat_data.a, roughness, metallic); #ifdef V3D_LIGHTING_MATCAP - /* When using matcaps, mat_data.a is the backface sign. */ + /* When using matcaps, mat_data.a is the back-face sign. */ N = (mat_data.a > 0.0) ? N : -N; fragColor.rgb = get_matcap_lighting(base_color, N, I); diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index be61b0a9baf..a0694a08f0b 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -36,7 +36,7 @@ typedef struct DRW_MeshWeightState { short flags; char alert_mode; - /* Set of all selected bones for Multipaint. */ + /* Set of all selected bones for Multi-paint. */ bool *defgroup_sel; /* [defgroup_len] */ int defgroup_sel_count; diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_private.h b/source/blender/draw/intern/draw_cache_extract_mesh_private.h index 2424b0f9fee..5f670bdc5ec 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_private.h +++ b/source/blender/draw/intern/draw_cache_extract_mesh_private.h @@ -30,6 +30,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "draw_cache_extract.h" diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c index 8f1f6b59e7a..74423513bcc 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.c +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c @@ -422,7 +422,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr .tri_len = 0, .curve_len = 0, }; - BKE_gpencil_visible_stroke_iter( + BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, gpencil_object_verts_count_cb, &iter, do_onion, cfra); /* Create VBOs. */ @@ -439,7 +439,8 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len); /* Fill buffers with data. */ - BKE_gpencil_visible_stroke_iter(NULL, ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra); + BKE_gpencil_visible_stroke_advanced_iter( + NULL, ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra); /* Mark last 2 verts as invalid. */ for (int i = 0; i < 2; i++) { @@ -514,7 +515,7 @@ GPUBatch *DRW_cache_gpencil_face_wireframe_get(Object *ob) /* IMPORTANT: Keep in sync with gpencil_edit_batches_ensure() */ bool do_onion = true; - BKE_gpencil_visible_stroke_iter( + BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, gpencil_lines_indices_cb, &iter, do_onion, cfra); GPUIndexBuf *ibo = GPU_indexbuf_build(&iter.ibo); @@ -856,7 +857,7 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in iter.verts = (gpEditVert *)GPU_vertbuf_get_data(cache->edit_vbo); /* Fill buffers with data. */ - BKE_gpencil_visible_stroke_iter( + BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, gpencil_edit_stroke_iter_cb, &iter, do_onion, cfra); /* Create the batches */ @@ -883,7 +884,7 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in cache->edit_curve_vbo = GPU_vertbuf_create_with_format(format); /* Count data. */ - BKE_gpencil_visible_stroke_iter( + BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, gpencil_edit_curve_stroke_count_cb, &iterdata, false, cfra); gpEditCurveIterData iter; @@ -894,7 +895,7 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in iter.verts = (gpEditCurveVert *)GPU_vertbuf_get_data(cache->edit_curve_vbo); /* Fill buffers with data. */ - BKE_gpencil_visible_stroke_iter( + BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, gpencil_edit_curve_stroke_iter_cb, &iter, false, cfra); cache->edit_curve_handles_batch = GPU_batch_create( diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 8387fb2f43f..0c002ff09f2 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -821,6 +821,17 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode) mesh_batch_cache_discard_shaded_tri(cache); mesh_batch_cache_discard_uvedit(cache); break; + case BKE_MESH_BATCH_DIRTY_DEFORM: + FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) { + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor); + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.lnor); + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_pos); + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_nor); + GPU_INDEXBUF_DISCARD_SAFE(mbufcache->ibo.tris); + } + batch_map = MDEPS_CREATE_MAP(vbo.pos_nor, vbo.lnor, vbo.fdots_pos, vbo.fdots_nor, ibo.tris); + mesh_batch_cache_discard_batch(cache, batch_map); + break; case BKE_MESH_BATCH_DIRTY_UVEDIT_ALL: mesh_batch_cache_discard_uvedit(cache); break; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 62742d082ca..6f5e041fa79 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1645,7 +1645,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_engines_draw_scene(); - /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */ + /* Fix 3D view "lagging" on APPLE and WIN32+NVIDIA. (See T56996, T61474) */ GPU_flush(); DRW_stats_reset(); diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 03679c51469..7f7696d485c 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -701,7 +701,7 @@ BLI_INLINE void draw_select_buffer(DRWShadingGroup *shgroup, int count = 1; int tot = is_instancing ? GPU_vertbuf_get_vertex_len(batch->inst[0]) : GPU_vertbuf_get_vertex_len(batch->verts[0]); - /* Hack : get "vbo" data without actually drawing. */ + /* HACK: get VBO data without actually drawing. */ int *select_id = (void *)GPU_vertbuf_get_data(state->select_buf); /* Batching */ diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index f69830fc015..87688ee343c 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4025,7 +4025,7 @@ static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac), /* conditionally supported */ case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) { - /* this should only appear in tweakmode */ + /* This should only appear in tweak-mode. */ return true; } else { @@ -5176,7 +5176,7 @@ void ANIM_channel_draw_widgets(const bContext *C, } /* step 3) draw special toggles ................................. - * - in Graph Editor, checkboxes for visibility in curves area + * - in Graph Editor, check-boxes for visibility in curves area * - in NLA Editor, glowing dots for solo/not solo... * - in Grease Pencil mode, color swatches for layer color */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 136cdefd2ec..8f8c1c067d4 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -747,7 +747,7 @@ static bool animedit_poll_channels_active(bContext *C) return 1; } -/* poll callback for Animation Editor channels list region + not in NLA-tweakmode for NLA */ +/* Poll callback for Animation Editor channels list region + not in NLA-tweak-mode for NLA. */ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C) { ScrArea *area = CTX_wm_area(C); @@ -763,7 +763,7 @@ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C) return 0; } - /* NLA TweakMode test */ + /* NLA tweak-mode test. */ if (area->spacetype == SPACE_NLA) { if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON)) { return 0; @@ -1283,6 +1283,9 @@ static void split_groups_action_temp(bAction *act, bActionGroup *tgrp) else { group_fcurves_last->next->prev = group_fcurves_first->prev; } + + /* Clear links pointing outside the per-group list. */ + group_fcurves_first->prev = group_fcurves_last->next = NULL; } /* Initialize memory for temp-group */ @@ -1337,24 +1340,12 @@ static void join_groups_action_temp(bAction *act) if (agrp->flag & AGRP_TEMP) { LISTBASE_FOREACH (FCurve *, fcu, &agrp->channels) { fcu->grp = NULL; - if (fcu == agrp->channels.last) { - break; - } } BLI_remlink(&act->groups, agrp); break; } } - - /* BLI_movelisttolist() doesn't touch first->prev and last->next pointers in its "dst" list. - * Ensure that after the reshuffling the list is properly terminated. */ - if (!BLI_listbase_is_empty(&act->curves)) { - FCurve *act_fcurves_first = act->curves.first; - act_fcurves_first->prev = NULL; - FCurve *act_fcurves_last = act->curves.last; - act_fcurves_last->next = NULL; - } } /* Change the order of anim-channels within action diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 73b9b118148..6f3277397c5 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -51,8 +51,10 @@ #include "DEG_depsgraph.h" +#include "SEQ_iterator.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" +#include "SEQ_transform.h" #include "anim_intern.h" @@ -81,6 +83,49 @@ static bool change_frame_poll(bContext *C) return false; } +static int seq_snap_threshold_get_frame_distance(bContext *C) +{ + const int snap_distance = SEQ_tool_settings_snap_distance_get(CTX_data_scene(C)); + const ARegion *region = CTX_wm_region(C); + return round_fl_to_int(UI_view2d_region_to_view_x(®ion->v2d, snap_distance) - + UI_view2d_region_to_view_x(®ion->v2d, 0)); +} + +static void seq_frame_snap_update_best(const int position, + const int timeline_frame, + int *r_best_frame, + int *r_best_distance) +{ + if (abs(position - timeline_frame) < *r_best_distance) { + *r_best_distance = abs(position - timeline_frame); + *r_best_frame = position; + } +} + +static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame) +{ + + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene, false)); + SeqCollection *strips = SEQ_query_all_strips(seqbase); + + int best_frame = 0; + int best_distance = MAXFRAME; + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, strips) { + seq_frame_snap_update_best( + SEQ_transform_get_left_handle_frame(seq), timeline_frame, &best_frame, &best_distance); + seq_frame_snap_update_best( + SEQ_transform_get_right_handle_frame(seq), timeline_frame, &best_frame, &best_distance); + } + SEQ_collection_free(strips); + + if (best_distance < seq_snap_threshold_get_frame_distance(C)) { + return best_frame; + } + + return timeline_frame; +} + /* Set the new frame number */ static void change_frame_apply(bContext *C, wmOperator *op) { @@ -90,7 +135,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) if (do_snap) { if (CTX_wm_space_seq(C)) { - frame = SEQ_time_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); + frame = seq_frame_apply_snap(C, scene, frame); } else { frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame); @@ -181,6 +226,18 @@ static void change_frame_seq_preview_end(bContext *C) } } +static bool use_sequencer_snapping(bContext *C) +{ + if (!CTX_wm_space_seq(C)) { + return false; + } + + Scene *scene = CTX_data_scene(C); + short snap_flag = SEQ_tool_settings_snap_flag_get(scene); + return (scene->toolsettings->snap_flag & SCE_SNAP_SEQ) && + (snap_flag & SEQ_SNAP_CURRENT_FRAME_TO_STRIPS); +} + /* Modal Operator init */ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event) { @@ -190,6 +247,10 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event */ RNA_float_set(op->ptr, "frame", frame_from_event(C, event)); + if (use_sequencer_snapping(C)) { + RNA_boolean_set(op->ptr, "snap", true); + } + change_frame_seq_preview_begin(C, event); change_frame_apply(C, op); @@ -231,11 +292,22 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event) case EVT_LEFTCTRLKEY: case EVT_RIGHTCTRLKEY: - if (event->val == KM_RELEASE) { - RNA_boolean_set(op->ptr, "snap", false); + /* Use Ctrl key to invert snapping in sequencer. */ + if (use_sequencer_snapping(C)) { + if (event->val == KM_RELEASE) { + RNA_boolean_set(op->ptr, "snap", true); + } + else if (event->val == KM_PRESS) { + RNA_boolean_set(op->ptr, "snap", false); + } } - else if (event->val == KM_PRESS) { - RNA_boolean_set(op->ptr, "snap", true); + else { + if (event->val == KM_RELEASE) { + RNA_boolean_set(op->ptr, "snap", false); + } + else if (event->val == KM_PRESS) { + RNA_boolean_set(op->ptr, "snap", true); + } } break; } diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 16eb2f6b6f2..bfaa76b3bf9 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -80,7 +80,7 @@ FCurve *verify_driver_fcurve(ID *id, /* init animdata if none available yet */ adt = BKE_animdata_from_id(id); if (adt == NULL && creation_mode != DRIVER_FCURVE_LOOKUP_ONLY) { - adt = BKE_animdata_add_id(id); + adt = BKE_animdata_ensure_id(id); } if (adt == NULL) { /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */ diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 3751555f18c..0a499232ba9 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -85,6 +85,8 @@ static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *prop, Scene *scene); +static int delete_key_using_keying_set(bContext *C, wmOperator *op, KeyingSet *ks); + /* ************************************************** */ /* Keyframing Setting Wrangling */ @@ -140,7 +142,7 @@ bAction *ED_id_action_ensure(Main *bmain, ID *id) /* init animdata if none available yet */ adt = BKE_animdata_from_id(id); if (adt == NULL) { - adt = BKE_animdata_add_id(id); + adt = BKE_animdata_ensure_id(id); } if (adt == NULL) { /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */ @@ -2079,42 +2081,19 @@ void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot) static int delete_key_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */ - int num_channels; - KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene); if (ks == NULL) { return OPERATOR_CANCELLED; } - const int prop_type = RNA_property_type(op->type->prop); - if (prop_type == PROP_ENUM) { - int type = RNA_property_enum_get(op->ptr, op->type->prop); - ks = ANIM_keyingset_get_from_enum_type(scene, type); - if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); - return OPERATOR_CANCELLED; - } - } - else if (prop_type == PROP_STRING) { - char type_id[MAX_ID_NAME - 2]; - RNA_property_string_get(op->ptr, op->type->prop, type_id); - ks = ANIM_keyingset_get_from_idname(scene, type_id); - - if (ks == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Active Keying Set '%s' not found", type_id); - return OPERATOR_CANCELLED; - } - } - else { - BLI_assert(0); - } + return delete_key_using_keying_set(C, op, ks); +} - /* report failure */ - if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); - return OPERATOR_CANCELLED; - } +static int delete_key_using_keying_set(bContext *C, wmOperator *op, KeyingSet *ks) +{ + Scene *scene = CTX_data_scene(C); + float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */ + int num_channels; /* try to delete keyframes for the channels specified by KeyingSet */ num_channels = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra); @@ -2130,7 +2109,8 @@ static int delete_key_exec(bContext *C, wmOperator *op) if (num_channels > 0) { /* if the appropriate properties have been set, make a note that we've inserted something */ - if (RNA_boolean_get(op->ptr, "confirm_success")) { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "confirm_success"); + if (prop != NULL && RNA_property_boolean_get(op->ptr, prop)) { BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", @@ -2301,7 +2281,7 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int delete_key_v3d_exec(bContext *C, wmOperator *op) +static int delete_key_v3d_without_keying_set(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); float cfra = (float)CFRA; @@ -2408,6 +2388,18 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int delete_key_v3d_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + KeyingSet *ks = ANIM_scene_get_active_keyingset(scene); + + if (ks == NULL) { + return delete_key_v3d_without_keying_set(C, op); + } + + return delete_key_using_keying_set(C, op, ks); +} + void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot) { /* identifiers */ diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index 034378399b9..6af033f3cf2 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -109,7 +109,7 @@ static void draw_current_frame(const Scene *scene, if (draw_line) { /* Draw vertical line to from the bottom of the current frame box to the bottom of the screen. */ - const float subframe_x = UI_view2d_view_to_region_x(v2d, BKE_scene_frame_get(scene)); + const float subframe_x = UI_view2d_view_to_region_x(v2d, BKE_scene_ctime_get(scene)); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c index 725945f8edc..832e75b2a8b 100644 --- a/source/blender/editors/armature/editarmature_undo.c +++ b/source/blender/editors/armature/editarmature_undo.c @@ -206,7 +206,7 @@ static void armature_undosys_step_decode(struct bContext *C, } undoarm_to_editarm(&elem->data, arm); arm->needs_flush_to_id = 1; - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(&arm->id, ID_RECALC_GEOMETRY); } /* The first element is always active */ diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c index 88f6398567d..210411c6eb5 100644 --- a/source/blender/editors/curve/editcurve_undo.c +++ b/source/blender/editors/curve/editcurve_undo.c @@ -267,7 +267,7 @@ static void curve_undosys_step_decode(struct bContext *C, } undocurve_to_editcurve(bmain, &elem->data, obedit->data, &obedit->shapenr); cu->editnurb->needs_flush_to_id = 1; - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY); } /* The first element is always active */ diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c index b61506d9346..6eaf8971eb0 100644 --- a/source/blender/editors/curve/editfont_undo.c +++ b/source/blender/editors/curve/editfont_undo.c @@ -379,7 +379,7 @@ static void font_undosys_step_decode(struct bContext *C, Curve *cu = obedit->data; undofont_to_editfont(&us->data, cu); - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY); ED_undo_object_set_active_or_warn( CTX_data_scene(C), CTX_data_view_layer(C), obedit, us_p->name, &LOG); diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 7bc4c307935..4b0c5ccd285 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -1172,7 +1172,7 @@ static void annotation_stroke_eraser_dostroke(tGPsdata *p, ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) { /* Check if point segment of stroke had anything to do with * eraser region (either within stroke painted, or on its lines) - * - this assumes that linewidth is irrelevant + * - this assumes that line-width is irrelevant. */ if (gpencil_stroke_inside_circle(mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { if ((annotation_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) || diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 0b107aac8b9..d6f6dbb2b10 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1579,7 +1579,7 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p, ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) { /* Check if point segment of stroke had anything to do with * eraser region (either within stroke painted, or on its lines) - * - this assumes that linewidth is irrelevant + * - this assumes that line-width is irrelevant. */ if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) { diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c index 7ec64b2afd6..16605b6c634 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_paint.c +++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c @@ -910,7 +910,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso, ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) { /* Check if point segment of stroke had anything to do with * brush region (either within stroke painted, or on its lines) - * - this assumes that linewidth is irrelevant + * - this assumes that line-width is irrelevant. */ if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c index 6e396cd82e3..d14322e12b5 100644 --- a/source/blender/editors/gpencil/gpencil_weight_paint.c +++ b/source/blender/editors/gpencil/gpencil_weight_paint.c @@ -448,7 +448,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso, ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) { /* Check if point segment of stroke had anything to do with * brush region (either within stroke painted, or on its lines) - * - this assumes that linewidth is irrelevant + * - this assumes that line-width is irrelevant. */ if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 0493832c06f..673f629d6ef 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -468,7 +468,7 @@ bool fcurve_is_changed(struct PointerRNA ptr, * Checks whether a keyframe exists for the given ID-block one the given frame. * - It is recommended to call this method over the other keyframe-checkers directly, * in case some detail of the implementation changes... - * - frame: the value of this is quite often result of #BKE_scene_frame_get() + * - frame: the value of this is quite often result of #BKE_scene_ctime_get() */ bool id_frame_has_keyframe(struct ID *id, float frame, short filter); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 667540b8f63..2b73194afb2 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -86,7 +86,7 @@ void EDBM_mesh_clear(struct BMEditMesh *em); void EDBM_selectmode_to_scene(struct bContext *C); void EDBM_mesh_make(struct Object *ob, const int select_mode, const bool add_key_index); -void EDBM_mesh_free(struct BMEditMesh *em); +void EDBM_mesh_free_data(struct BMEditMesh *em); void EDBM_mesh_load_ex(struct Main *bmain, struct Object *ob, bool free_data); void EDBM_mesh_load(struct Main *bmain, struct Object *ob); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 7a8c14d0a35..802c175492f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -58,6 +58,7 @@ struct bNodeTree; struct bScreen; struct rctf; struct rcti; +struct uiBlockInteraction_Handle; struct uiButSearch; struct uiFontStyle; struct uiList; @@ -245,7 +246,7 @@ enum { #define UI_PANEL_BOX_STYLE_MARGIN (U.widget_unit * 0.2f) /* but->drawflag - these flags should only affect how the button is drawn. */ -/* NOTE: currently, these flags _are not passed_ to the widget's state() or draw() functions +/* NOTE: currently, these flags *are not passed* to the widget's state() or draw() functions * (except for the 'align' ones)! */ enum { @@ -514,6 +515,54 @@ typedef int (*uiButPushedStateFunc)(struct uiBut *but, const void *arg); typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event); +/* -------------------------------------------------------------------- */ +/** \name Custom Interaction + * + * Sometimes it's useful to create data that remains available + * while the user interacts with a button. + * + * A common case is dragging a number button or slider + * however this could be used in other cases too. + * \{ */ + +struct uiBlockInteraction_Params { + /** + * When true, this interaction is not modal + * (user clicking on a number button arrows or pasting a value for example). + */ + bool is_click; + /** + * Array of unique event ID's (values from #uiBut.retval). + * There may be more than one for multi-button editing (see #UI_BUT_DRAG_MULTI). + */ + int *unique_retval_ids; + uint unique_retval_ids_len; +}; + +/** Returns 'user_data', freed by #uiBlockInteractionEndFn. */ +typedef void *(*uiBlockInteractionBeginFn)(struct bContext *C, + const struct uiBlockInteraction_Params *params, + void *arg1); +typedef void (*uiBlockInteractionEndFn)(struct bContext *C, + const struct uiBlockInteraction_Params *params, + void *arg1, + void *user_data); +typedef void (*uiBlockInteractionUpdateFn)(struct bContext *C, + const struct uiBlockInteraction_Params *params, + void *arg1, + void *user_data); + +typedef struct uiBlockInteraction_CallbackData { + uiBlockInteractionBeginFn begin_fn; + uiBlockInteractionEndFn end_fn; + uiBlockInteractionUpdateFn update_fn; + void *arg1; +} uiBlockInteraction_CallbackData; + +void UI_block_interaction_set(uiBlock *block, uiBlockInteraction_CallbackData *callbacks); + +/** \} */ + /* Menu Callbacks */ typedef void (*uiMenuCreateFunc)(struct bContext *C, struct uiLayout *layout, void *arg1); @@ -663,7 +712,7 @@ enum { UI_BLOCK_THEME_STYLE_POPUP = 1, }; void UI_block_theme_style_set(uiBlock *block, char theme_style); -char UI_block_emboss_get(uiBlock *block); +eUIEmbossType UI_block_emboss_get(uiBlock *block); void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss); bool UI_block_is_search_only(const uiBlock *block); void UI_block_set_search_only(uiBlock *block, bool search_only); @@ -678,7 +727,7 @@ void UI_block_region_set(uiBlock *block, struct ARegion *region); void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr); void UI_block_lock_clear(uiBlock *block); -/* automatic aligning, horiz or verical */ +/* Automatic aligning, horizontal or vertical. */ void UI_block_align_begin(uiBlock *block); void UI_block_align_end(uiBlock *block); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index e9784a59d70..32b86119753 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3542,7 +3542,7 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eU return block; } -char UI_block_emboss_get(uiBlock *block) +eUIEmbossType UI_block_emboss_get(uiBlock *block) { return block->emboss; } @@ -4106,7 +4106,6 @@ static uiBut *ui_def_but(uiBlock *block, UI_BTYPE_BLOCK, UI_BTYPE_BUT_MENU, UI_BTYPE_SEARCH_MENU, - UI_BTYPE_PROGRESS_BAR, UI_BTYPE_DATASETROW, UI_BTYPE_POPOVER)) { but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index de0d5a4a3d7..2a7611eabb1 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -560,7 +560,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0; /* Set the (button_pointer, button_prop) - * and pointer data for Python access to the hovered ui element. */ + * and pointer data for Python access to the hovered UI element. */ uiLayoutSetContextFromBut(layout, but); /* Keyframes */ diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 2bd1b404228..655fdda3069 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -229,7 +229,7 @@ void ui_draw_but_TAB_outline(const rcti *rect, {0.98, 0.805}, }; - /* mult */ + /* Multiply. */ for (a = 0; a < 4; a++) { mul_v2_fl(vec[a], rad); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index bf81ccd280e..0e45970a165 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -35,10 +35,12 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "BLI_array_utils.h" #include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" +#include "BLI_sort_utils.h" #include "BLI_string.h" #include "BLI_string_cursor_utf8.h" #include "BLI_string_utf8.h" @@ -170,6 +172,20 @@ static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but static void ui_textedit_string_set(uiBut *but, struct uiHandleButtonData *data, const char *str); static void button_tooltip_timer_reset(bContext *C, uiBut *but); +static void ui_block_interaction_begin_ensure(bContext *C, + uiBlock *block, + struct uiHandleButtonData *data, + const bool is_click); +static struct uiBlockInteraction_Handle *ui_block_interaction_begin(struct bContext *C, + uiBlock *block, + const bool is_click); +static void ui_block_interaction_end(struct bContext *C, + uiBlockInteraction_CallbackData *callbacks, + struct uiBlockInteraction_Handle *interaction); +static void ui_block_interaction_update(struct bContext *C, + uiBlockInteraction_CallbackData *callbacks, + struct uiBlockInteraction_Handle *interaction); + #ifdef USE_KEYNAV_LIMIT static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEvent *event); static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEvent *event); @@ -225,6 +241,19 @@ typedef enum uiMenuScrollType { MENU_SCROLL_BOTTOM, } uiMenuScrollType; +typedef struct uiBlockInteraction_Handle { + struct uiBlockInteraction_Params params; + void *user_data; + /** + * This is shared between #uiHandleButtonData and #uiAfterFunc, + * the last user runs the end callback and frees the data. + * + * This is needed as the order of freeing changes depending on + * accepting/canceling the operation. + */ + int user_count; +} uiBlockInteraction_Handle; + #ifdef USE_ALLSELECT /* Unfortunately there's no good way handle more generally: @@ -430,6 +459,8 @@ typedef struct uiHandleButtonData { uiSelectContextStore select_others; #endif + struct uiBlockInteraction_Handle *custom_interaction_handle; + /* Text field undo. */ struct uiUndoStack_Text *undo_stack_text; @@ -471,6 +502,9 @@ typedef struct uiAfterFunc { void *search_arg; uiFreeArgFunc search_arg_free_fn; + uiBlockInteraction_CallbackData custom_interaction_callbacks; + uiBlockInteraction_Handle *custom_interaction_handle; + bContextStore *context; char undostr[BKE_UNDO_STR_MAX]; @@ -769,72 +803,95 @@ static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but) (block->handle && block->handle->popup_op)); } +/** + * These functions are postponed and only executed after all other + * handling is done, i.e. menus are closed, in order to avoid conflicts + * with these functions removing the buttons we are working with. + */ static void ui_apply_but_func(bContext *C, uiBut *but) { uiBlock *block = but->block; + if (!ui_afterfunc_check(block, but)) { + return; + } - /* these functions are postponed and only executed after all other - * handling is done, i.e. menus are closed, in order to avoid conflicts - * with these functions removing the buttons we are working with */ - - if (ui_afterfunc_check(block, but)) { - uiAfterFunc *after = ui_afterfunc_new(); + uiAfterFunc *after = ui_afterfunc_new(); - if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) { - /* exception, this will crash due to removed button otherwise */ - but->func(C, but->func_arg1, but->func_arg2); - } - else { - after->func = but->func; - } + if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) { + /* exception, this will crash due to removed button otherwise */ + but->func(C, but->func_arg1, but->func_arg2); + } + else { + after->func = but->func; + } - after->func_arg1 = but->func_arg1; - after->func_arg2 = but->func_arg2; + after->func_arg1 = but->func_arg1; + after->func_arg2 = but->func_arg2; - after->funcN = but->funcN; - after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL; + after->funcN = but->funcN; + after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL; - after->rename_func = but->rename_func; - after->rename_arg1 = but->rename_arg1; - after->rename_orig = but->rename_orig; /* needs free! */ + after->rename_func = but->rename_func; + after->rename_arg1 = but->rename_arg1; + after->rename_orig = but->rename_orig; /* needs free! */ - after->handle_func = block->handle_func; - after->handle_func_arg = block->handle_func_arg; - after->retval = but->retval; + after->handle_func = block->handle_func; + after->handle_func_arg = block->handle_func_arg; + after->retval = but->retval; - if (but->type == UI_BTYPE_BUT_MENU) { - after->butm_func = block->butm_func; - after->butm_func_arg = block->butm_func_arg; - after->a2 = but->a2; - } + if (but->type == UI_BTYPE_BUT_MENU) { + after->butm_func = block->butm_func; + after->butm_func_arg = block->butm_func_arg; + after->a2 = but->a2; + } - if (block->handle) { - after->popup_op = block->handle->popup_op; - } + if (block->handle) { + after->popup_op = block->handle->popup_op; + } - after->optype = but->optype; - after->opcontext = but->opcontext; - after->opptr = but->opptr; + after->optype = but->optype; + after->opcontext = but->opcontext; + after->opptr = but->opptr; - after->rnapoin = but->rnapoin; - after->rnaprop = but->rnaprop; + after->rnapoin = but->rnapoin; + after->rnaprop = but->rnaprop; - if (but->type == UI_BTYPE_SEARCH_MENU) { - uiButSearch *search_but = (uiButSearch *)but; - after->search_arg_free_fn = search_but->arg_free_fn; - after->search_arg = search_but->arg; - search_but->arg_free_fn = NULL; - search_but->arg = NULL; - } + if (but->type == UI_BTYPE_SEARCH_MENU) { + uiButSearch *search_but = (uiButSearch *)but; + after->search_arg_free_fn = search_but->arg_free_fn; + after->search_arg = search_but->arg; + search_but->arg_free_fn = NULL; + search_but->arg = NULL; + } - if (but->context) { - after->context = CTX_store_copy(but->context); + if (but->active != NULL) { + uiHandleButtonData *data = but->active; + if (data->custom_interaction_handle != NULL) { + after->custom_interaction_callbacks = block->custom_interaction_callbacks; + after->custom_interaction_handle = data->custom_interaction_handle; + + /* Ensure this callback runs once and last. */ + uiAfterFunc *after_prev = after->prev; + if (after_prev && + (after_prev->custom_interaction_handle == data->custom_interaction_handle)) { + after_prev->custom_interaction_handle = NULL; + memset(&after_prev->custom_interaction_callbacks, + 0x0, + sizeof(after_prev->custom_interaction_callbacks)); + } + else { + after->custom_interaction_handle->user_count++; + } } + } - but->optype = NULL; - but->opcontext = 0; - but->opptr = NULL; + if (but->context) { + after->context = CTX_store_copy(but->context); } + + but->optype = NULL; + but->opcontext = 0; + but->opptr = NULL; } /* typically call ui_apply_but_undo(), ui_apply_but_autokey() */ @@ -997,6 +1054,18 @@ static void ui_apply_but_funcs_after(bContext *C) after.search_arg_free_fn(after.search_arg); } + if (after.custom_interaction_handle != NULL) { + after.custom_interaction_handle->user_count--; + BLI_assert(after.custom_interaction_handle->user_count >= 0); + if (after.custom_interaction_handle->user_count == 0) { + ui_block_interaction_update( + C, &after.custom_interaction_callbacks, after.custom_interaction_handle); + ui_block_interaction_end( + C, &after.custom_interaction_callbacks, after.custom_interaction_handle); + } + after.custom_interaction_handle = NULL; + } + ui_afterfunc_update_preferences_dirty(&after); if (after.undostr[0]) { @@ -2283,6 +2352,11 @@ static void ui_apply_but( uiButCurveProfile *but_profile = (uiButCurveProfile *)but; but_profile->edit_profile = editprofile; } + + if (data->custom_interaction_handle != NULL) { + ui_block_interaction_update( + C, &block->custom_interaction_callbacks, data->custom_interaction_handle); + } } /** \} */ @@ -3268,7 +3342,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in } #ifdef WITH_INPUT_IME -/* enable ime, and set up uibut ime data */ +/* Enable IME, and setup #uiBut IME data. */ static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but)) { /* XXX Is this really needed? */ @@ -3284,7 +3358,7 @@ static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but)) wm_window_IME_begin(win, x, y, 0, 0, true); } -/* disable ime, and clear uibut ime data */ +/* Disable IME, and clear #uiBut IME data. */ static void ui_textedit_ime_end(wmWindow *win, uiBut *UNUSED(but)) { wm_window_IME_end(win); @@ -4852,6 +4926,8 @@ static bool ui_numedit_but_NUM(uiButNumber *number_but, return changed; } + ui_block_interaction_begin_ensure(but->block->evil_C, but->block, data, false); + if (ui_but_is_cursor_warp(but)) { const float softmin = but->softmin; const float softmax = but->softmax; @@ -5362,6 +5438,8 @@ static bool ui_numedit_but_SLI(uiBut *but, return changed; } + ui_block_interaction_begin_ensure(but->block->evil_C, but->block, data, false); + const PropertyScaleType scale_type = ui_but_scale_type(but); softmin = but->softmin; @@ -8239,6 +8317,16 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s but->flag &= ~UI_SELECT; } + if (state == BUTTON_STATE_TEXT_EDITING) { + ui_block_interaction_begin_ensure(C, but->block, data, true); + } + else if (state == BUTTON_STATE_EXIT) { + if (data->state == BUTTON_STATE_NUM_EDITING) { + /* This happens on pasting values for example. */ + ui_block_interaction_begin_ensure(C, but->block, data, true); + } + } + data->state = state; if (state != BUTTON_STATE_EXIT) { @@ -8467,6 +8555,21 @@ static void button_activate_exit( ED_region_tag_redraw_no_rebuild(data->region); ED_region_tag_refresh_ui(data->region); + if ((but->flag & UI_BUT_DRAG_MULTI) == 0) { + if (data->custom_interaction_handle != NULL) { + /* Should only set when the button is modal. */ + BLI_assert(but->active != NULL); + data->custom_interaction_handle->user_count--; + + BLI_assert(data->custom_interaction_handle->user_count >= 0); + if (data->custom_interaction_handle->user_count == 0) { + ui_block_interaction_end( + C, &but->block->custom_interaction_callbacks, data->custom_interaction_handle); + } + data->custom_interaction_handle = NULL; + } + } + /* clean up button */ if (but->active) { MEM_freeN(but->active); @@ -11314,3 +11417,100 @@ bool UI_but_active_drop_color(bContext *C) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name UI Block Interaction API + * \{ */ + +void UI_block_interaction_set(uiBlock *block, uiBlockInteraction_CallbackData *callbacks) +{ + block->custom_interaction_callbacks = *callbacks; +} + +static uiBlockInteraction_Handle *ui_block_interaction_begin(bContext *C, + uiBlock *block, + const bool is_click) +{ + BLI_assert(block->custom_interaction_callbacks.begin_fn != NULL); + uiBlockInteraction_Handle *interaction = MEM_callocN(sizeof(*interaction), __func__); + + int unique_retval_ids_len = 0; + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { + if (but->active || (but->flag & UI_BUT_DRAG_MULTI)) { + unique_retval_ids_len++; + } + } + + int *unique_retval_ids = MEM_mallocN(sizeof(*unique_retval_ids) * unique_retval_ids_len, + __func__); + unique_retval_ids_len = 0; + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { + if (but->active || (but->flag & UI_BUT_DRAG_MULTI)) { + unique_retval_ids[unique_retval_ids_len++] = but->retval; + } + } + + if (unique_retval_ids_len > 1) { + qsort(unique_retval_ids, unique_retval_ids_len, sizeof(int), BLI_sortutil_cmp_int); + unique_retval_ids_len = BLI_array_deduplicate_ordered(unique_retval_ids, + unique_retval_ids_len); + unique_retval_ids = MEM_reallocN(unique_retval_ids, + sizeof(*unique_retval_ids) * unique_retval_ids_len); + } + + interaction->params.is_click = is_click; + interaction->params.unique_retval_ids = unique_retval_ids; + interaction->params.unique_retval_ids_len = unique_retval_ids_len; + + interaction->user_data = block->custom_interaction_callbacks.begin_fn( + C, &interaction->params, block->custom_interaction_callbacks.arg1); + return interaction; +} + +static void ui_block_interaction_end(bContext *C, + uiBlockInteraction_CallbackData *callbacks, + uiBlockInteraction_Handle *interaction) +{ + BLI_assert(callbacks->end_fn != NULL); + callbacks->end_fn(C, &interaction->params, callbacks->arg1, interaction->user_data); + MEM_freeN(interaction->params.unique_retval_ids); + MEM_freeN(interaction); +} + +static void ui_block_interaction_update(bContext *C, + uiBlockInteraction_CallbackData *callbacks, + uiBlockInteraction_Handle *interaction) +{ + BLI_assert(callbacks->update_fn != NULL); + callbacks->update_fn(C, &interaction->params, callbacks->arg1, interaction->user_data); +} + +/** + * \note #ui_block_interaction_begin cannot be called when setting the button state + * (e.g. #BUTTON_STATE_NUM_EDITING) for the following reasons. + * + * - Other buttons may still be activated using #UI_BUT_DRAG_MULTI + * which is necessary before gathering all the #uiBut.retval values to initialize + * #uiBlockInteraction_Params.unique_retval_ids. + * - When clicking on a number button it's not known if the event is a click or a drag. + * + * Instead, it must be called immediately before the drag action begins. + */ +static void ui_block_interaction_begin_ensure(bContext *C, + uiBlock *block, + uiHandleButtonData *data, + const bool is_click) +{ + if (data->custom_interaction_handle) { + return; + } + if (block->custom_interaction_callbacks.begin_fn == NULL) { + return; + } + + uiBlockInteraction_Handle *interaction = ui_block_interaction_begin(C, block, is_click); + interaction->user_count = 1; + data->custom_interaction_handle = interaction; +} + +/** \} */ diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index c9253e1f675..aa957afbf8f 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1519,7 +1519,7 @@ static void icon_draw_rect(float x, draw_h = h; draw_x += (w - draw_w) / 2; } - /* if the image is squared, the draw_ initialization values are good */ + /* If the image is squared, the `draw_*` initialization values are good. */ /* first allocate imbuf for scaling and copy preview into it */ ima = IMB_allocImBuf(rw, rh, 32, IB_rect); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index a05afb6e542..40a9c67c630 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -511,6 +511,9 @@ struct uiBlock { uiBlockHandleFunc handle_func; void *handle_func_arg; + /** Custom interaction data. */ + uiBlockInteraction_CallbackData custom_interaction_callbacks; + /** Custom extra event handling. */ int (*block_event_func)(const struct bContext *C, struct uiBlock *, const struct wmEvent *); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index abebc09ace2..8b9539f1d33 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1411,7 +1411,7 @@ BLI_INLINE bool ui_layout_is_radial(const uiLayout *layout) } /** - * Create ui items for enum items in \a item_array. + * Create UI items for enum items in \a item_array. * * A version of #uiItemsFullEnumO that takes pre-calculated item array. */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e85ec40ac73..9c17486aea4 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2399,8 +2399,8 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single( op->type->ui((bContext *)C, op); op->layout = NULL; - /* UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. We could - * allow ot.ui callback to return this, but not needed right now. */ + /* #UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. + * We could allow #wmOperatorType.ui callback to return this, but not needed right now. */ } else { wmWindowManager *wm = CTX_wm_manager(C); @@ -4015,23 +4015,23 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) case UICURVE_FUNC_RESET_VIEW: BKE_curvemapping_reset_view(cumap); break; - case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */ + case UICURVE_FUNC_HANDLE_VECTOR: /* Set vector. */ BKE_curvemap_handle_set(cuma, HD_VECT); BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_HANDLE_AUTO: /* set auto */ + case UICURVE_FUNC_HANDLE_AUTO: /* Set auto. */ BKE_curvemap_handle_set(cuma, HD_AUTO); BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */ + case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* Set auto-clamped. */ BKE_curvemap_handle_set(cuma, HD_AUTO_ANIM); BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */ + case UICURVE_FUNC_EXTEND_HOZ: /* Extend horizontal. */ cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE; BKE_curvemapping_changed(cumap, false); break; - case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */ + case UICURVE_FUNC_EXTEND_EXP: /* Extend extrapolate. */ cumap->flag |= CUMA_EXTEND_EXTRAPOLATE; BKE_curvemapping_changed(cumap, false); break; diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 057c33c779c..7ea02226f02 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -701,7 +701,7 @@ int UI_calc_float_precision(int prec, double value) /* Check on the number of decimal places need to display the number, * this is so 0.00001 is not displayed as 0.00, - * _but_, this is only for small values si 10.0001 will not get the same treatment. + * _but_, this is only for small values as 10.0001 will not get the same treatment. */ value = fabs(value); if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index f4d9c95ae09..72847fb2476 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1377,8 +1377,6 @@ static int ui_but_draw_menu_icon(const uiBut *but) static void widget_draw_icon( const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const uchar mono_color[4]) { - float xs = 0.0f, ys = 0.0f; - if (but->flag & UI_BUT_ICON_PREVIEW) { GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(icon, alpha, rect); @@ -1420,6 +1418,7 @@ static void widget_draw_icon( if (icon && icon != ICON_BLANK1) { const float ofs = 1.0f / aspect; + float xs, ys; if (but->drawflag & UI_BUT_ICON_LEFT) { /* special case - icon_only pie buttons */ @@ -2088,7 +2087,7 @@ static void widget_draw_text(const uiFontStyle *fstyle, but_pos_ofs = but->pos; #ifdef WITH_INPUT_IME - /* if is ime compositing, move the cursor */ + /* If is IME compositing, move the cursor. */ if (ime_data && ime_data->composite_len && ime_data->cursor_pos != -1) { but_pos_ofs += ime_data->cursor_pos; } @@ -2140,12 +2139,12 @@ static void widget_draw_text(const uiFontStyle *fstyle, } #ifdef WITH_INPUT_IME - /* ime cursor following */ + /* IME cursor following. */ if (ime_reposition_window) { ui_but_ime_reposition(but, ime_win_x, ime_win_y, false); } if (ime_data && ime_data->composite_len) { - /* composite underline */ + /* Composite underline. */ widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr); } #endif @@ -3720,10 +3719,6 @@ static void widget_progressbar( /* "slider" bar color */ copy_v3_v3_uchar(wcol->inner, wcol->item); widgetbase_draw(&wtb_bar, wcol); - - /* raise text a bit */ - rect->xmin += (BLI_rcti_size_x(&rect_prog) / 2); - rect->xmax += (BLI_rcti_size_x(&rect_prog) / 2); } static void widget_datasetrow( diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 73bcaee735e..1fd1b6c984d 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1745,7 +1745,7 @@ typedef struct v2dScrollerMove { * This is a CUT DOWN VERSION of the 'real' version, which is defined in view2d.c, * as we only need focus bubble info. * - * \warning: The start of this struct must not change, + * \warning The start of this struct must not change, * so that it stays in sync with the 'real' version. * For now, we don't need to have a separate (internal) header for structs like this... */ diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index 28838d677f0..12890552b1d 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -63,10 +63,26 @@ # include "WM_api.h" # include "WM_types.h" +# include "DEG_depsgraph.h" + # include "io_alembic.h" # include "ABC_alembic.h" +const EnumPropertyItem rna_enum_abc_export_evaluation_mode_items[] = { + {DAG_EVAL_RENDER, + "RENDER", + 0, + "Render", + "Use Render settings for object visibility, modifier settings, etc"}, + {DAG_EVAL_VIEWPORT, + "VIEWPORT", + 0, + "Viewport", + "Use Viewport settings for object visibility, modifier settings, etc"}, + {0, NULL, 0, NULL, NULL}, +}; + static int wm_alembic_export_invoke(bContext *C, wmOperator *op, const wmEvent *event) { if (!RNA_struct_property_is_set(op->ptr, "as_background_job")) { @@ -126,7 +142,6 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op) .curves_as_mesh = RNA_boolean_get(op->ptr, "curves_as_mesh"), .flatten_hierarchy = RNA_boolean_get(op->ptr, "flatten"), .visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only"), - .renderable_only = RNA_boolean_get(op->ptr, "renderable_only"), .face_sets = RNA_boolean_get(op->ptr, "face_sets"), .use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"), .export_hair = RNA_boolean_get(op->ptr, "export_hair"), @@ -137,6 +152,7 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op) .triangulate = RNA_boolean_get(op->ptr, "triangulate"), .quad_method = RNA_enum_get(op->ptr, "quad_method"), .ngon_method = RNA_enum_get(op->ptr, "ngon_method"), + .evaluation_mode = RNA_enum_get(op->ptr, "evaluation_mode"), .global_scale = RNA_float_get(op->ptr, "global_scale"), }; @@ -194,9 +210,11 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr) sub = uiLayoutColumnWithHeading(col, true, IFACE_("Only")); uiItemR(sub, imfptr, "selected", 0, IFACE_("Selected Objects"), ICON_NONE); - uiItemR(sub, imfptr, "renderable_only", 0, IFACE_("Renderable Objects"), ICON_NONE); uiItemR(sub, imfptr, "visible_objects_only", 0, IFACE_("Visible Objects"), ICON_NONE); + col = uiLayoutColumn(box, true); + uiItemR(col, imfptr, "evaluation_mode", 0, NULL, ICON_NONE); + /* Object Data */ box = uiLayoutBox(layout); row = uiLayoutRow(box, false); @@ -355,12 +373,6 @@ void WM_OT_alembic_export(wmOperatorType *ot) ot->srna, "selected", 0, "Selected Objects Only", "Export only selected objects"); RNA_def_boolean(ot->srna, - "renderable_only", - 1, - "Renderable Objects Only", - "Export only objects marked renderable in the outliner"); - - RNA_def_boolean(ot->srna, "visible_objects_only", 0, "Visible Objects Only", @@ -468,6 +480,14 @@ void WM_OT_alembic_export(wmOperatorType *ot) "This option is deprecated; EXECUTE this operator to run in the foreground, and INVOKE it " "to run as a background job"); + RNA_def_enum(ot->srna, + "evaluation_mode", + rna_enum_abc_export_evaluation_mode_items, + DAG_EVAL_RENDER, + "Use Settings for", + "Determines visibility of objects, modifier settings, and other areas where there " + "are different settings for viewport and rendering"); + /* This dummy prop is used to check whether we need to init the start and * end frame values to that of the scene's, otherwise they are reset at * every change, draw update. */ diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c index d92a81179cc..23eaf991fd3 100644 --- a/source/blender/editors/lattice/editlattice_undo.c +++ b/source/blender/editors/lattice/editlattice_undo.c @@ -240,7 +240,7 @@ static void lattice_undosys_step_decode(struct bContext *C, } undolatt_to_editlatt(&elem->data, lt->editlatt); lt->editlatt->needs_flush_to_id = 1; - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(<->id, ID_RECALC_GEOMETRY); } /* The first element is always active */ diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index 942fe143787..09b17acf56d 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -30,6 +30,7 @@ #include "BKE_context.h" #include "BKE_curve.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index 993905462db..cccfc7e934c 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -126,7 +126,7 @@ static int geometry_extract_apply(bContext *C, .calc_face_normal = true, })); - BMEditMesh *em = BKE_editmesh_create(bm, false); + BMEditMesh *em = BKE_editmesh_create(bm); /* Generate the tags for deleting geometry in the extracted object. */ tag_fn(bm, params); @@ -206,7 +206,7 @@ static int geometry_extract_apply(bContext *C, }), mesh); - BKE_editmesh_free(em); + BKE_editmesh_free_data(em); MEM_freeN(em); if (new_mesh->totvert == 0) { diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c index 593545ddcef..30a453a32ee 100644 --- a/source/blender/editors/mesh/editmesh_path.c +++ b/source/blender/editors/mesh/editmesh_path.c @@ -29,6 +29,7 @@ #include "DNA_windowmanager_types.h" #ifdef WITH_FREESTYLE +# include "BKE_customdata.h" # include "DNA_meshdata_types.h" #endif diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 132a442343c..830c9abb41e 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -35,6 +35,7 @@ #include "BLI_utildefines_stack.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_layer.h" diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index f52ab48785d..c452f7a7487 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -29,6 +29,7 @@ #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_layer.h" diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 4d383140d80..41a9f426798 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -44,6 +44,7 @@ #include "BLI_string.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_key.h" @@ -973,7 +974,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op) #ifdef USE_FACE_CREATE_SEL_EXTEND /* normally we would want to leave the new geometry selected, * but being able to press F many times to add geometry is too useful! */ - if (ele_desel && (BMO_slot_buffer_count(bmop.slots_out, "faces.out") == 1) && + if (ele_desel && (BMO_slot_buffer_len(bmop.slots_out, "faces.out") == 1) && (ele_desel_face = BMO_slot_buffer_get_first(bmop.slots_out, "faces.out"))) { edbm_add_edge_face_exec__tricky_finalize_sel(em->bm, ele_desel, ele_desel_face); } @@ -2344,7 +2345,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) BMO_slot_buffer_hflag_enable( em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true); - const int tot_rotate = BMO_slot_buffer_count(bmop.slots_out, "edges.out"); + const int tot_rotate = BMO_slot_buffer_len(bmop.slots_out, "edges.out"); const int tot_failed = tot - tot_rotate; tot_rotate_all += tot_rotate; @@ -6560,7 +6561,7 @@ enum { typedef struct BMElemSort { /** Sort factor */ float srt; - /** Original index of this element _in its mempool_ */ + /** Original index of this element (in its #BLI_mempool). */ int org_idx; } BMElemSort; diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 112de68b52c..fc9e1aa8b1a 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -33,6 +33,7 @@ #include "BLI_listbase.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_key.h" #include "BKE_layer.h" @@ -671,7 +672,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key * em->bm->shapenr = um->shapenr; - EDBM_mesh_free(em); + EDBM_mesh_free_data(em); bm = BM_mesh_create(&allocsize, &((struct BMeshCreateParams){ @@ -681,13 +682,21 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key * BM_mesh_bm_from_me(bm, &um->me, (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, + /* Handled with tessellation. */ + .calc_face_normal = false, .active_shapekey = um->shapenr, })); - em_tmp = BKE_editmesh_create(bm, true); + em_tmp = BKE_editmesh_create(bm); *em = *em_tmp; + /* Calculate face normals and tessellation at once since it's multi-threaded. + * The vertex normals are stored in the undo-mesh, so this doesn't need to be updated. */ + BKE_editmesh_looptri_calc_ex(em, + &(const struct BMeshCalcTessellation_Params){ + .face_normals = true, + }); + em->selectmode = um->selectmode; bm->selectmode = um->selectmode; @@ -865,7 +874,7 @@ static void mesh_undosys_step_decode(struct bContext *C, BMEditMesh *em = me->edit_mesh; undomesh_to_editmesh(&elem->data, obedit, em, me->key); em->needs_flush_to_id = 1; - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY); } /* The first element is always active */ diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 4f416c94f62..85c646d689c 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -305,17 +305,13 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index) if (me->edit_mesh) { /* this happens when switching shape keys */ - EDBM_mesh_free(me->edit_mesh); + EDBM_mesh_free_data(me->edit_mesh); MEM_freeN(me->edit_mesh); } - /* currently executing operators re-tessellates, so we can avoid doing here - * but at some point it may need to be added back. */ -#if 0 - me->edit_mesh = BKE_editmesh_create(bm, true); -#else - me->edit_mesh = BKE_editmesh_create(bm, false); -#endif + /* Executing operators re-tessellates, + * so we can avoid doing here but at some point it may need to be added back. */ + me->edit_mesh = BKE_editmesh_create(bm); me->edit_mesh->selectmode = me->edit_mesh->bm->selectmode = select_mode; me->edit_mesh->mat_nr = (ob->actcol > 0) ? ob->actcol - 1 : 0; @@ -326,7 +322,8 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index) /** * \warning This can invalidate the #Mesh runtime cache of other objects (for linked duplicates). - * Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913 + * Most callers should run #DEG_id_tag_update on `ob->data`, see: T46738, T46913. + * This ensures #BKE_object_free_derived_caches runs on all objects that use this mesh. */ void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data) { @@ -346,25 +343,6 @@ void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data) .calc_object_remap = true, .update_shapekey_indices = !free_data, })); - - /* Free derived mesh. usually this would happen through depsgraph but there - * are exceptions like file save that will not cause this, and we want to - * avoid ending up with an invalid derived mesh then. - * - * Do it for all objects which shares the same mesh datablock, since their - * derived meshes might also be referencing data which was just freed, - * - * Annoying enough, but currently seems most efficient way to avoid access - * of freed data on scene update, especially in cases when there are dependency - * cycles. - */ -#if 0 - for (Object *other_object = bmain->objects.first; other_object != NULL; other_object = other_object->id.next) { - if (other_object->data == ob->data) { - BKE_object_free_derived_caches(other_object); - } - } -#endif } void EDBM_mesh_clear(BMEditMesh *em) @@ -372,8 +350,8 @@ void EDBM_mesh_clear(BMEditMesh *em) /* clear bmesh */ BM_mesh_clear(em->bm); - /* free derived meshes */ - BKE_editmesh_free_derivedmesh(em); + /* Free evaluated meshes & cache. */ + BKE_editmesh_free_derived_caches(em); /* free tessellation data */ em->tottri = 0; @@ -389,9 +367,9 @@ void EDBM_mesh_load(Main *bmain, Object *ob) } /** - * Should only be called on the active editmesh, otherwise call #BKE_editmesh_free + * Should only be called on the active edit-mesh, otherwise call #BKE_editmesh_free_data. */ -void EDBM_mesh_free(BMEditMesh *em) +void EDBM_mesh_free_data(BMEditMesh *em) { /* These tables aren't used yet, so it's not strictly necessary * to 'end' them but if someone tries to start using them, @@ -399,7 +377,7 @@ void EDBM_mesh_free(BMEditMesh *em) ED_mesh_mirror_spatial_table_end(NULL); ED_mesh_mirror_topo_table_end(NULL); - BKE_editmesh_free(em); + BKE_editmesh_free_data(em); } /** \} */ @@ -1471,8 +1449,8 @@ void EDBM_update(Mesh *mesh, const struct EDBMUpdate_Params *params) BM_lnorspace_invalidate(em->bm, false); em->bm->spacearr_dirty &= ~BM_SPACEARR_BMO_SET; } - /* don't keep stale derivedMesh data around, see: T38872. */ - BKE_editmesh_free_derivedmesh(em); + /* Don't keep stale evaluated mesh data around, see: T38872. */ + BKE_editmesh_free_derived_caches(em); #ifdef DEBUG { diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 2b78d83a9f5..73b3fb9724e 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -34,6 +34,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_mesh.h" #include "BKE_report.h" diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c index a8b471a7c92..f7b53b5513f 100644 --- a/source/blender/editors/metaball/editmball_undo.c +++ b/source/blender/editors/metaball/editmball_undo.c @@ -215,7 +215,7 @@ static void mball_undosys_step_decode(struct bContext *C, } undomball_to_editmball(&elem->data, mb); mb->needs_flush_to_id = 1; - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY); } /* The first element is always active */ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 6d22da2c2bc..8ae74fbfafa 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1845,7 +1845,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) * ready to be moved around to re-time the sound and/or make new sound clips. */ { /* create new data for NLA hierarchy */ - AnimData *adt = BKE_animdata_add_id(&ob->id); + AnimData *adt = BKE_animdata_ensure_id(&ob->id); NlaTrack *nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, ob->data); strip->start = CFRA; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 1cb6a5c8ff5..6108691b2f1 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -557,7 +557,7 @@ static bool ED_object_editmode_load_free_ex(Main *bmain, } if (free_data) { - EDBM_mesh_free(me->edit_mesh); + EDBM_mesh_free_data(me->edit_mesh); MEM_freeN(me->edit_mesh); me->edit_mesh = NULL; } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 30f75e9a150..d7177eabcba 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2061,6 +2061,23 @@ static void single_object_action_users( FOREACH_OBJECT_FLAG_END; } +static void single_objectdata_action_users( + Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, const int flag) +{ + FOREACH_OBJECT_FLAG_BEGIN (scene, view_layer, v3d, flag, ob) { + if (!ID_IS_LINKED(ob) && ob->data != NULL) { + ID *id_obdata = (ID *)ob->data; + AnimData *adt = BKE_animdata_from_id(id_obdata); + ID *id_act = (ID *)adt->action; + if (id_act && id_act->us > 1) { + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + BKE_animdata_copy_id_action(bmain, id_obdata); + } + } + } + FOREACH_OBJECT_FLAG_END; +} + static void single_mat_users( Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, const int flag) { @@ -2643,6 +2660,10 @@ static int make_single_user_exec(bContext *C, wmOperator *op) single_object_action_users(bmain, scene, view_layer, v3d, flag); } + if (RNA_boolean_get(op->ptr, "obdata_animation")) { + single_objectdata_action_users(bmain, scene, view_layer, v3d, flag); + } + BKE_main_id_newptr_and_tag_clear(bmain); WM_event_add_notifier(C, NC_WINDOW, NULL); @@ -2684,8 +2705,16 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot) RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects"); RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data"); RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each data-block"); - RNA_def_boolean( - ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object"); + RNA_def_boolean(ot->srna, + "animation", + 0, + "Object Animation", + "Make object animation data local to each object"); + RNA_def_boolean(ot->srna, + "obdata_animation", + 0, + "Object Data Animation", + "Make object data (mesh, curve etc.) animation data local to each object"); } /** \} */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index e350653e178..4c4727f51ee 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -1152,51 +1152,53 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) for (int object_index = 0; object_index < num_objects; object_index++) { Object *ob = objects[object_index]; + if (ob->flag & OB_DONE) { + continue; + } - if ((ob->flag & OB_DONE) == 0) { - bool do_inverse_offset = false; - ob->flag |= OB_DONE; + bool do_inverse_offset = false; + ob->flag |= OB_DONE; - if (centermode == ORIGIN_TO_CURSOR) { - copy_v3_v3(cent, cursor); - invert_m4_m4(ob->imat, ob->obmat); - mul_m4_v3(ob->imat, cent); - } + if (centermode == ORIGIN_TO_CURSOR) { + copy_v3_v3(cent, cursor); + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_v3(ob->imat, cent); + } - if (ob->data == NULL) { - /* special support for dupligroups */ - if ((ob->transflag & OB_DUPLICOLLECTION) && ob->instance_collection && - (ob->instance_collection->id.tag & LIB_TAG_DOIT) == 0) { - if (ID_IS_LINKED(ob->instance_collection)) { - tot_lib_error++; + if (ob->data == NULL) { + /* special support for dupligroups */ + if ((ob->transflag & OB_DUPLICOLLECTION) && ob->instance_collection && + (ob->instance_collection->id.tag & LIB_TAG_DOIT) == 0) { + if (ID_IS_LINKED(ob->instance_collection)) { + tot_lib_error++; + } + else { + if (centermode == ORIGIN_TO_CURSOR) { + /* done */ } else { - if (centermode == ORIGIN_TO_CURSOR) { - /* done */ - } - else { - float min[3], max[3]; - /* only bounds support */ - INIT_MINMAX(min, max); - BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true); - mid_v3_v3v3(cent, min, max); - invert_m4_m4(ob->imat, ob->obmat); - mul_m4_v3(ob->imat, cent); - } + float min[3], max[3]; + /* only bounds support */ + INIT_MINMAX(min, max); + BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true); + mid_v3_v3v3(cent, min, max); + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_v3(ob->imat, cent); + } - add_v3_v3(ob->instance_collection->instance_offset, cent); + add_v3_v3(ob->instance_collection->instance_offset, cent); - tot_change++; - ob->instance_collection->id.tag |= LIB_TAG_DOIT; - do_inverse_offset = true; - } + tot_change++; + ob->instance_collection->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; } } - else if (ID_IS_LINKED(ob->data)) { - tot_lib_error++; - } - - if (obedit == NULL && ob->type == OB_MESH) { + } + else if (ID_IS_LINKED(ob->data)) { + tot_lib_error++; + } + else if (ob->type == OB_MESH) { + if (obedit == NULL) { Mesh *me = ob->data; if (centermode == ORIGIN_TO_CURSOR) { @@ -1222,265 +1224,265 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) me->id.tag |= LIB_TAG_DOIT; do_inverse_offset = true; } - else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { - Curve *cu = ob->data; + } + else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu = ob->data; - if (centermode == ORIGIN_TO_CURSOR) { - /* done */ - } - else if (around == V3D_AROUND_CENTER_BOUNDS) { - BKE_curve_center_bounds(cu, cent); - } - else { /* #V3D_AROUND_CENTER_MEDIAN. */ - BKE_curve_center_median(cu, cent); - } + if (centermode == ORIGIN_TO_CURSOR) { + /* done */ + } + else if (around == V3D_AROUND_CENTER_BOUNDS) { + BKE_curve_center_bounds(cu, cent); + } + else { /* #V3D_AROUND_CENTER_MEDIAN. */ + BKE_curve_center_median(cu, cent); + } - /* don't allow Z change if curve is 2D */ - if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) { - cent[2] = 0.0; - } + /* don't allow Z change if curve is 2D */ + if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) { + cent[2] = 0.0; + } - negate_v3_v3(cent_neg, cent); - BKE_curve_translate(cu, cent_neg, 1); + negate_v3_v3(cent_neg, cent); + BKE_curve_translate(cu, cent_neg, 1); - tot_change++; - cu->id.tag |= LIB_TAG_DOIT; - do_inverse_offset = true; + tot_change++; + cu->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; - if (obedit) { - if (centermode == GEOMETRY_TO_ORIGIN) { - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); - } - break; + if (obedit) { + if (centermode == GEOMETRY_TO_ORIGIN) { + DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); } + break; } - else if (ob->type == OB_FONT) { - /* Get from bounding-box. */ + } + else if (ob->type == OB_FONT) { + /* Get from bounding-box. */ - Curve *cu = ob->data; + Curve *cu = ob->data; - if (ob->runtime.bb == NULL && (centermode != ORIGIN_TO_CURSOR)) { - /* Do nothing. */ + if (ob->runtime.bb == NULL && (centermode != ORIGIN_TO_CURSOR)) { + /* Do nothing. */ + } + else { + if (centermode == ORIGIN_TO_CURSOR) { + /* Done. */ } else { - if (centermode == ORIGIN_TO_CURSOR) { - /* Done. */ - } - else { - /* extra 0.5 is the height o above line */ - cent[0] = 0.5f * (ob->runtime.bb->vec[4][0] + ob->runtime.bb->vec[0][0]); - cent[1] = 0.5f * (ob->runtime.bb->vec[0][1] + ob->runtime.bb->vec[2][1]); - } + /* extra 0.5 is the height o above line */ + cent[0] = 0.5f * (ob->runtime.bb->vec[4][0] + ob->runtime.bb->vec[0][0]); + cent[1] = 0.5f * (ob->runtime.bb->vec[0][1] + ob->runtime.bb->vec[2][1]); + } - cent[2] = 0.0f; + cent[2] = 0.0f; - cu->xof = cu->xof - cent[0]; - cu->yof = cu->yof - cent[1]; + cu->xof = cu->xof - cent[0]; + cu->yof = cu->yof - cent[1]; - tot_change++; - cu->id.tag |= LIB_TAG_DOIT; - do_inverse_offset = true; - } + tot_change++; + cu->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; } - else if (ob->type == OB_ARMATURE) { - bArmature *arm = ob->data; + } + else if (ob->type == OB_ARMATURE) { + bArmature *arm = ob->data; - if (ID_REAL_USERS(arm) > 1) { + if (ID_REAL_USERS(arm) > 1) { #if 0 BKE_report(op->reports, RPT_ERROR, "Cannot apply to a multi user armature"); return; #endif - tot_multiuser_arm_error++; - } - else { - /* Function to recenter armatures in editarmature.c - * Bone + object locations are handled there. - */ - ED_armature_origin_set(bmain, ob, cursor, centermode, around); + tot_multiuser_arm_error++; + } + else { + /* Function to recenter armatures in editarmature.c + * Bone + object locations are handled there. + */ + ED_armature_origin_set(bmain, ob, cursor, centermode, around); - tot_change++; - arm->id.tag |= LIB_TAG_DOIT; - /* do_inverse_offset = true; */ /* docenter_armature() handles this */ + tot_change++; + arm->id.tag |= LIB_TAG_DOIT; + /* do_inverse_offset = true; */ /* docenter_armature() handles this */ - Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); - BKE_object_transform_copy(ob_eval, ob); - BKE_armature_copy_bone_transforms(ob_eval->data, ob->data); - BKE_object_where_is_calc(depsgraph, scene, ob_eval); - BKE_pose_where_is(depsgraph, scene, ob_eval); /* needed for bone parents */ + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + BKE_object_transform_copy(ob_eval, ob); + BKE_armature_copy_bone_transforms(ob_eval->data, ob->data); + BKE_object_where_is_calc(depsgraph, scene, ob_eval); + BKE_pose_where_is(depsgraph, scene, ob_eval); /* needed for bone parents */ - ignore_parent_tx(bmain, depsgraph, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); - if (obedit) { - break; - } + if (obedit) { + break; } } - else if (ob->type == OB_MBALL) { - MetaBall *mb = ob->data; + } + else if (ob->type == OB_MBALL) { + MetaBall *mb = ob->data; - if (centermode == ORIGIN_TO_CURSOR) { - /* done */ - } - else if (around == V3D_AROUND_CENTER_BOUNDS) { - BKE_mball_center_bounds(mb, cent); - } - else { /* #V3D_AROUND_CENTER_MEDIAN. */ - BKE_mball_center_median(mb, cent); - } + if (centermode == ORIGIN_TO_CURSOR) { + /* done */ + } + else if (around == V3D_AROUND_CENTER_BOUNDS) { + BKE_mball_center_bounds(mb, cent); + } + else { /* #V3D_AROUND_CENTER_MEDIAN. */ + BKE_mball_center_median(mb, cent); + } - negate_v3_v3(cent_neg, cent); - BKE_mball_translate(mb, cent_neg); + negate_v3_v3(cent_neg, cent); + BKE_mball_translate(mb, cent_neg); - tot_change++; - mb->id.tag |= LIB_TAG_DOIT; - do_inverse_offset = true; + tot_change++; + mb->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; - if (obedit) { - if (centermode == GEOMETRY_TO_ORIGIN) { - DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); - } - break; + if (obedit) { + if (centermode == GEOMETRY_TO_ORIGIN) { + DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY); } + break; } - else if (ob->type == OB_LATTICE) { - Lattice *lt = ob->data; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = ob->data; - if (centermode == ORIGIN_TO_CURSOR) { - /* done */ - } - else if (around == V3D_AROUND_CENTER_BOUNDS) { - BKE_lattice_center_bounds(lt, cent); - } - else { /* #V3D_AROUND_CENTER_MEDIAN. */ - BKE_lattice_center_median(lt, cent); - } + if (centermode == ORIGIN_TO_CURSOR) { + /* done */ + } + else if (around == V3D_AROUND_CENTER_BOUNDS) { + BKE_lattice_center_bounds(lt, cent); + } + else { /* #V3D_AROUND_CENTER_MEDIAN. */ + BKE_lattice_center_median(lt, cent); + } - negate_v3_v3(cent_neg, cent); - BKE_lattice_translate(lt, cent_neg, 1); + negate_v3_v3(cent_neg, cent); + BKE_lattice_translate(lt, cent_neg, 1); - tot_change++; - lt->id.tag |= LIB_TAG_DOIT; - do_inverse_offset = true; - } - else if (ob->type == OB_GPENCIL) { - bGPdata *gpd = ob->data; - float gpcenter[3]; - if (gpd) { - if (centermode == ORIGIN_TO_GEOMETRY) { - zero_v3(gpcenter); - BKE_gpencil_centroid_3d(gpd, gpcenter); - add_v3_v3(gpcenter, ob->obmat[3]); - } - if (centermode == ORIGIN_TO_CURSOR) { - copy_v3_v3(gpcenter, cursor); - } - if (ELEM(centermode, ORIGIN_TO_GEOMETRY, ORIGIN_TO_CURSOR)) { - bGPDspoint *pt; - float imat[3][3], bmat[3][3]; - float offset_global[3]; - float offset_local[3]; - int i; - - sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]); - copy_m3_m4(bmat, obact->obmat); - invert_m3_m3(imat, bmat); - mul_m3_v3(imat, offset_global); - mul_v3_m3v3(offset_local, imat, offset_global); - - float diff_mat[4][4]; - float inverse_diff_mat[4][4]; - - /* recalculate all strokes - * (all layers are considered without evaluating lock attributes) */ - LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { - /* calculate difference matrix */ - BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat); - /* undo matrix */ - invert_m4_m4(inverse_diff_mat, diff_mat); - LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { - LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - float mpt[3]; - mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x); - sub_v3_v3(mpt, offset_local); - mul_v3_m4v3(&pt->x, diff_mat, mpt); - } + tot_change++; + lt->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; + } + else if (ob->type == OB_GPENCIL) { + bGPdata *gpd = ob->data; + float gpcenter[3]; + if (gpd) { + if (centermode == ORIGIN_TO_GEOMETRY) { + zero_v3(gpcenter); + BKE_gpencil_centroid_3d(gpd, gpcenter); + add_v3_v3(gpcenter, ob->obmat[3]); + } + if (centermode == ORIGIN_TO_CURSOR) { + copy_v3_v3(gpcenter, cursor); + } + if (ELEM(centermode, ORIGIN_TO_GEOMETRY, ORIGIN_TO_CURSOR)) { + bGPDspoint *pt; + float imat[3][3], bmat[3][3]; + float offset_global[3]; + float offset_local[3]; + int i; + + sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]); + copy_m3_m4(bmat, obact->obmat); + invert_m3_m3(imat, bmat); + mul_m3_v3(imat, offset_global); + mul_v3_m3v3(offset_local, imat, offset_global); + + float diff_mat[4][4]; + float inverse_diff_mat[4][4]; + + /* recalculate all strokes + * (all layers are considered without evaluating lock attributes) */ + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + /* calculate difference matrix */ + BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat); + /* undo matrix */ + invert_m4_m4(inverse_diff_mat, diff_mat); + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + float mpt[3]; + mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x); + sub_v3_v3(mpt, offset_local); + mul_v3_m4v3(&pt->x, diff_mat, mpt); } } } - tot_change++; - if (centermode == ORIGIN_TO_GEOMETRY) { - copy_v3_v3(ob->loc, gpcenter); - } - DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); - - ob->id.tag |= LIB_TAG_DOIT; - do_inverse_offset = true; } - else { - BKE_report(op->reports, - RPT_WARNING, - "Grease Pencil Object does not support this set origin option"); + tot_change++; + if (centermode == ORIGIN_TO_GEOMETRY) { + copy_v3_v3(ob->loc, gpcenter); } + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + + ob->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; + } + else { + BKE_report(op->reports, + RPT_WARNING, + "Grease Pencil Object does not support this set origin option"); } } + } - /* offset other selected objects */ - if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { - float obmat[4][4]; + /* offset other selected objects */ + if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { + float obmat[4][4]; - /* was the object data modified - * NOTE: the functions above must set 'cent'. */ + /* was the object data modified + * NOTE: the functions above must set 'cent'. */ - /* convert the offset to parent space */ - BKE_object_to_mat4(ob, obmat); - mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */ + /* convert the offset to parent space */ + BKE_object_to_mat4(ob, obmat); + mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */ - add_v3_v3(ob->loc, centn); + add_v3_v3(ob->loc, centn); - Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); - BKE_object_transform_copy(ob_eval, ob); - BKE_object_where_is_calc(depsgraph, scene, ob_eval); - if (ob->type == OB_ARMATURE) { - /* needed for bone parents */ - BKE_armature_copy_bone_transforms(ob_eval->data, ob->data); - BKE_pose_where_is(depsgraph, scene, ob_eval); - } - - ignore_parent_tx(bmain, depsgraph, scene, ob); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + BKE_object_transform_copy(ob_eval, ob); + BKE_object_where_is_calc(depsgraph, scene, ob_eval); + if (ob->type == OB_ARMATURE) { + /* needed for bone parents */ + BKE_armature_copy_bone_transforms(ob_eval->data, ob->data); + BKE_pose_where_is(depsgraph, scene, ob_eval); + } - /* other users? */ - // CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) - //{ - - /* use existing context looper */ - for (int other_object_index = 0; other_object_index < num_objects; other_object_index++) { - Object *ob_other = objects[other_object_index]; - - if ((ob_other->flag & OB_DONE) == 0 && - ((ob->data && (ob->data == ob_other->data)) || - (ob->instance_collection == ob_other->instance_collection && - (ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION))) { - ob_other->flag |= OB_DONE; - DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - - mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */ - add_v3_v3(ob_other->loc, centn); - - Object *ob_other_eval = DEG_get_evaluated_object(depsgraph, ob_other); - BKE_object_transform_copy(ob_other_eval, ob_other); - BKE_object_where_is_calc(depsgraph, scene, ob_other_eval); - if (ob_other->type == OB_ARMATURE) { - /* needed for bone parents */ - BKE_armature_copy_bone_transforms(ob_eval->data, ob->data); - BKE_pose_where_is(depsgraph, scene, ob_other_eval); - } - ignore_parent_tx(bmain, depsgraph, scene, ob_other); + ignore_parent_tx(bmain, depsgraph, scene, ob); + + /* other users? */ + // CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //{ + + /* use existing context looper */ + for (int other_object_index = 0; other_object_index < num_objects; other_object_index++) { + Object *ob_other = objects[other_object_index]; + + if ((ob_other->flag & OB_DONE) == 0 && + ((ob->data && (ob->data == ob_other->data)) || + (ob->instance_collection == ob_other->instance_collection && + (ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION))) { + ob_other->flag |= OB_DONE; + DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + + mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */ + add_v3_v3(ob_other->loc, centn); + + Object *ob_other_eval = DEG_get_evaluated_object(depsgraph, ob_other); + BKE_object_transform_copy(ob_other_eval, ob_other); + BKE_object_where_is_calc(depsgraph, scene, ob_other_eval); + if (ob_other->type == OB_ARMATURE) { + /* needed for bone parents */ + BKE_armature_copy_bone_transforms(ob_eval->data, ob->data); + BKE_pose_where_is(depsgraph, scene, ob_other_eval); } + ignore_parent_tx(bmain, depsgraph, scene, ob_other); } - // CTX_DATA_END; } + // CTX_DATA_END; } } MEM_freeN(objects); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index c591931805d..39de63c22a9 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1539,8 +1539,8 @@ static void region_rect_recursive( region->winx = BLI_rcti_size_x(®ion->winrct) + 1; region->winy = BLI_rcti_size_y(®ion->winrct) + 1; - /* if region opened normally, we store this for hide/reveal usage */ - /* prevent rounding errors for UI_DPI_FAC mult and divide */ + /* If region opened normally, we store this for hide/reveal usage. */ + /* Prevent rounding errors for UI_DPI_FAC multiply and divide. */ if (region->winx > 1) { region->sizex = (region->winx + 0.5f) / UI_DPI_FAC; } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index a888958b9be..bd05d309421 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -2052,7 +2052,7 @@ static bool line_clip_rect2f(const rctf *cliprect, float l2_clip[2]) { /* first account for horizontal, then vertical lines */ - /* horiz */ + /* Horizontal. */ if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) { /* is the line out of range on its Y axis? */ if (l1[1] < rect->ymin || l1[1] > rect->ymax) { diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index da34723eed4..d968b6cc319 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -293,8 +293,8 @@ typedef struct SculptGestureContext { /* These store the view origin and normal in world space, which is used in some gestures to * generate geometry aligned from the view directly in world space. */ /* World space view origin and normal are not affected by object symmetry when doing symmetry - * passes, so there is no separate variables with the true_ prefix to store their original values - * without symmetry modifications. */ + * passes, so there is no separate variables with the `true_` prefix to store their original + * values without symmetry modifications. */ float world_space_view_origin[3]; float world_space_view_normal[3]; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index fe7029c7457..f21c900941b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -1608,7 +1608,7 @@ void ED_sculpt_undosys_type(UndoType *ut) ut->step_decode = sculpt_undosys_step_decode; ut->step_free = sculpt_undosys_step_free; - ut->flags = 0; + ut->flags = UNDOTYPE_FLAG_DECODE_ACTIVE_STEP; ut->step_size = sizeof(SculptUndoStep); } diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c index 9e69b0a72db..d69c7ab8d48 100644 --- a/source/blender/editors/space_action/action_data.c +++ b/source/blender/editors/space_action/action_data.c @@ -813,7 +813,7 @@ static int action_layer_next_exec(bContext *C, wmOperator *op) NlaTrack *act_track; Scene *scene = CTX_data_scene(C); - float ctime = BKE_scene_frame_get(scene); + float ctime = BKE_scene_ctime_get(scene); /* Get active track */ act_track = BKE_nlatrack_find_tweaked(adt); @@ -925,7 +925,7 @@ static int action_layer_prev_exec(bContext *C, wmOperator *op) NlaTrack *nlt; Scene *scene = CTX_data_scene(C); - float ctime = BKE_scene_frame_get(scene); + float ctime = BKE_scene_ctime_get(scene); /* Sanity Check */ if (adt == NULL) { diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 4d568017b4f..faa4b3cc9cc 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -523,6 +523,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) char orgname[FILE_MAX + 12]; char filename[FILE_MAX + 12]; wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); ARegion *region = CTX_wm_region(C); FileSelectParams *params = ED_fileselect_get_active_params(sfile); @@ -542,12 +543,16 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) else { /* If rename is successful, scroll to newly renamed entry. */ BLI_strncpy(params->renamefile, filename, sizeof(params->renamefile)); - file_params_invoke_rename_postscroll(wm, CTX_wm_window(C), sfile); + file_params_invoke_rename_postscroll(wm, win, sfile); } /* to make sure we show what is on disk */ ED_fileselect_clear(wm, sfile); } + else { + /* Renaming failed, reset the name for further renaming handling. */ + BLI_strncpy(params->renamefile, oldname, sizeof(params->renamefile)); + } ED_region_tag_redraw(region); } @@ -812,6 +817,8 @@ static void draw_details_columns(const FileSelectParams *params, void file_draw_list(const bContext *C, ARegion *region) { + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_get_active_params(sfile); FileLayout *layout = ED_fileselect_get_layout(sfile, region); @@ -882,12 +889,12 @@ void file_draw_list(const bContext *C, ARegion *region) // printf("%s: preview task: %d\n", __func__, previews_running); if (previews_running && !sfile->previews_timer) { sfile->previews_timer = WM_event_add_timer_notifier( - CTX_wm_manager(C), CTX_wm_window(C), NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01); + wm, win, NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01); } if (!previews_running && sfile->previews_timer) { /* Preview is not running, no need to keep generating update events! */ // printf("%s: Inactive preview task, sleeping!\n", __func__); - WM_event_remove_timer_notifier(CTX_wm_manager(C), CTX_wm_window(C), sfile->previews_timer); + WM_event_remove_timer_notifier(wm, win, sfile->previews_timer); sfile->previews_timer = NULL; } } @@ -998,8 +1005,19 @@ void file_draw_list(const bContext *C, ARegion *region) UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ UI_but_flag_disable(but, UI_BUT_UNDO); if (false == UI_but_active_only(C, region, block, but)) { - file_selflag = filelist_entry_select_set( - sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL); + /* Note that this is the only place where we can also handle a cancelled renaming. */ + + file_params_rename_end(wm, win, sfile, file); + + /* After the rename button is removed, we need to make sure the view is redrawn once more, + * in case selection changed. Usually UI code would trigger that redraw, but the rename + * operator may have been called from a different region. + * Tagging regions for redrawing while drawing is rightfully prevented. However, this + * active button removing basically introduces handling logic to drawing code. So a + * notifier should be an acceptable workaround. */ + WM_event_add_notifier_ex(wm, win, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + + file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL); } } diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index b2182c45f2a..0bbed65671c 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -109,6 +109,7 @@ FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d, float file_string_width(const char *str); float file_font_pointsize(void); +void file_select_deselect_all(SpaceFile *sfile, uint flag); int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file); int autocomplete_directory(struct bContext *C, char *str, void *arg_v); int autocomplete_file(struct bContext *C, char *str, void *arg_v); @@ -120,6 +121,10 @@ void file_params_renamefile_clear(struct FileSelectParams *params); void file_params_invoke_rename_postscroll(struct wmWindowManager *wm, struct wmWindow *win, SpaceFile *sfile); +void file_params_rename_end(struct wmWindowManager *wm, + struct wmWindow *win, + SpaceFile *sfile, + struct FileDirEntry *rename_file); void file_params_renamefile_activate(struct SpaceFile *sfile, struct FileSelectParams *params); typedef void *onReloadFnData; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 612f3a67aa3..995383d9d0e 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -104,15 +104,6 @@ static FileSelection find_file_mouse_rect(SpaceFile *sfile, return sel; } -static void file_deselect_all(SpaceFile *sfile, uint flag) -{ - FileSelection sel; - sel.first = 0; - sel.last = filelist_files_ensure(sfile->files) - 1; - - filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL); -} - typedef enum FileSelect { FILE_SELECT_NOTHING = 0, FILE_SELECT_DIR = 1, @@ -239,7 +230,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen) } /** - * \warning: loops over all files so better use cautiously + * \warning Loops over all files so better use cautiously. */ static bool file_is_any_selected(struct FileList *files) { @@ -444,7 +435,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve if ((sel.first != params->sel_first) || (sel.last != params->sel_last)) { int idx; - file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED); + file_select_deselect_all(sfile, FILE_SEL_HIGHLIGHTED); filelist_entries_select_index_range_set( sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); @@ -472,7 +463,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve params->highlight_file = -1; params->sel_first = params->sel_last = -1; fileselect_file_set(sfile, params->active_file); - file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED); + file_select_deselect_all(sfile, FILE_SEL_HIGHLIGHTED); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } @@ -491,7 +482,7 @@ static int file_box_select_exec(bContext *C, wmOperator *op) const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode"); const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - file_deselect_all(sfile, FILE_SEL_SELECTED); + file_select_deselect_all(sfile, FILE_SEL_SELECTED); } ED_fileselect_layout_isect_rect(sfile->layout, ®ion->v2d, &rect, &rect); @@ -573,7 +564,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) if ((idx >= 0) && (idx < numfiles)) { /* single select, deselect all selected first */ if (!extend) { - file_deselect_all(sfile, FILE_SEL_SELECTED); + file_select_deselect_all(sfile, FILE_SEL_SELECTED); } } } @@ -588,7 +579,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) if (ret == FILE_SELECT_NOTHING) { if (deselect_all) { - file_deselect_all(sfile, FILE_SEL_SELECTED); + file_select_deselect_all(sfile, FILE_SEL_SELECTED); } } else if (ret == FILE_SELECT_DIR) { @@ -721,7 +712,7 @@ static bool file_walk_select_selection_set(wmWindow *win, } else { /* deselect all first */ - file_deselect_all(sfile, FILE_SEL_SELECTED); + file_select_deselect_all(sfile, FILE_SEL_SELECTED); /* highlight file under mouse pos */ params->highlight_file = -1; @@ -2349,6 +2340,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) /* If we don't enter the directory directly, remember file to jump into editing. */ if (do_diropen == false) { + BLI_assert(params->rename_id == NULL || !"File rename handling should immediately clear rename_id when done, because otherwise it will keep taking precedence over renamefile."); BLI_strncpy(params->renamefile, name, FILE_MAXFILE); rename_flag = FILE_PARAMS_RENAME_PENDING; } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index ecd21907ed1..0e15538e03b 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -2016,19 +2016,21 @@ FileDirEntry *filelist_file(struct FileList *filelist, int index) return filelist_file_ex(filelist, index, true); } -int filelist_file_findpath(struct FileList *filelist, const char *filename) +/** + * Find a file from a file name, or more precisely, its file-list relative path, inside the + * filtered items. \return The index of the found file or -1. + */ +int filelist_file_find_path(struct FileList *filelist, const char *filename) { - int fidx = -1; - if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { - return fidx; + return -1; } /* XXX TODO: Cache could probably use a ghash on paths too? Not really urgent though. * This is only used to find again renamed entry, * annoying but looks hairy to get rid of it currently. */ - for (fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { + for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx]; if (STREQ(entry->relpath, filename)) { return fidx; @@ -2039,6 +2041,26 @@ int filelist_file_findpath(struct FileList *filelist, const char *filename) } /** + * Find a file representing \a id. + * \return The index of the found file or -1. + */ +int filelist_file_find_id(const FileList *filelist, const ID *id) +{ + if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { + return -1; + } + + for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { + FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx]; + if (entry->local_data.id == id) { + return fidx; + } + } + + return -1; +} + +/** * Get the ID a file represents (if any). For #FILE_MAIN, #FILE_MAIN_ASSET. */ ID *filelist_file_get_id(const FileDirEntry *file) @@ -2068,9 +2090,6 @@ void filelist_uid_unset(FileUID *r_uid) *r_uid = FILE_UID_UNSET; } -/** - * \warning: The UID will only be valid for the current session. Use as runtime data only! - */ void filelist_file_cache_slidingwindow_set(FileList *filelist, size_t window_size) { /* Always keep it power of 2, in [256, 8192] range for now, diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index e6c4b8e1a07..0aace74e621 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -97,7 +97,8 @@ int filelist_needs_reading(struct FileList *filelist); FileDirEntry *filelist_file(struct FileList *filelist, int index); FileDirEntry *filelist_file_ex(struct FileList *filelist, int index, bool use_request); -int filelist_file_findpath(struct FileList *filelist, const char *file); +int filelist_file_find_path(struct FileList *filelist, const char *file); +int filelist_file_find_id(const struct FileList *filelist, const struct ID *id); struct ID *filelist_file_get_id(const struct FileDirEntry *file); bool filelist_uid_is_set(const FileUID uid); void filelist_uid_unset(FileUID *r_uid); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 4e59e4ba06e..b7accbf71e5 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -1086,6 +1086,15 @@ void ED_file_change_dir(bContext *C) ED_file_change_dir_ex(C, area); } +void file_select_deselect_all(SpaceFile *sfile, uint flag) +{ + FileSelection sel; + sel.first = 0; + sel.last = filelist_files_ensure(sfile->files) - 1; + + filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL); +} + int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file) { int match = 0; @@ -1237,7 +1246,7 @@ void file_params_smoothscroll_timer_clear(wmWindowManager *wm, wmWindow *win, Sp * Set the renaming-state to #FILE_PARAMS_RENAME_POSTSCROLL_PENDING and trigger the smooth-scroll * timer. To be used right after a file was renamed. * Note that the caller is responsible for setting the correct rename-file info - * (#FileSelectParams.renamefile or #FileSelectParams.renamefile_uuid). + * (#FileSelectParams.renamefile or #FileSelectParams.rename_id). */ void file_params_invoke_rename_postscroll(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile) { @@ -1252,12 +1261,40 @@ void file_params_invoke_rename_postscroll(wmWindowManager *wm, wmWindow *win, Sp sfile->scroll_offset = 0; } +/** + * To be executed whenever renaming ends (successfully or not). + */ +void file_params_rename_end(wmWindowManager *wm, + wmWindow *win, + SpaceFile *sfile, + FileDirEntry *rename_file) +{ + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + + filelist_entry_select_set( + sfile->files, rename_file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL); + + /* Ensure smooth-scroll timer is active, even if not needed, because that way rename state is + * handled properly. */ + file_params_invoke_rename_postscroll(wm, win, sfile); + /* Also always activate the rename file, even if renaming was cancelled. */ + file_params_renamefile_activate(sfile, params); +} + void file_params_renamefile_clear(FileSelectParams *params) { params->renamefile[0] = '\0'; + params->rename_id = NULL; params->rename_flag = 0; } +static int file_params_find_renamed(const FileSelectParams *params, struct FileList *filelist) +{ + /* Find the file either through the local ID/asset it represents or its relative path. */ + return (params->rename_id != NULL) ? filelist_file_find_id(filelist, params->rename_id) : + filelist_file_find_path(filelist, params->renamefile); +} + /** * Helper used by both main update code, and smooth-scroll timer, * to try to enable rename editing from #FileSelectParams.renamefile name. @@ -1271,20 +1308,26 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) return; } - BLI_assert(params->renamefile[0] != '\0'); + BLI_assert(params->renamefile[0] != '\0' || params->rename_id != NULL); - const int idx = filelist_file_findpath(sfile->files, params->renamefile); + const int idx = file_params_find_renamed(params, sfile->files); if (idx >= 0) { FileDirEntry *file = filelist_file(sfile->files, idx); BLI_assert(file != NULL); + params->active_file = idx; + filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); + if ((params->rename_flag & FILE_PARAMS_RENAME_PENDING) != 0) { filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL); params->rename_flag = FILE_PARAMS_RENAME_ACTIVE; } else if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_PENDING) != 0) { - filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL); - params->renamefile[0] = '\0'; + file_select_deselect_all(sfile, FILE_SEL_SELECTED); + filelist_entry_select_set( + sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED, CHECK_ALL); + params->active_file = idx; + file_params_renamefile_clear(params); params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE; } } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 64b43ac74a5..05d484d8e2e 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -32,6 +32,7 @@ #include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_screen.h" #include "RNA_access.h" @@ -469,10 +470,19 @@ static void file_listener(const wmSpaceTypeListenerParams *listener_params) break; case NC_ID: { switch (wmn->action) { - case NA_RENAME: + case NA_RENAME: { + const ID *active_file_id = ED_fileselect_active_asset_get(sfile); + /* If a renamed ID is active in the file browser, update scrolling to keep it in view. */ + if (active_file_id && (wmn->reference == active_file_id)) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + params->rename_id = active_file_id; + file_params_invoke_rename_postscroll(G_MAIN->wm.first, listener_params->window, sfile); + } + /* Force list to update sorting (with a full reset for now). */ file_reset_filelist_showing_main_data(area, sfile); break; + } } break; } diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c index 082f66b57af..cc6effd0f71 100644 --- a/source/blender/editors/space_image/image_undo.c +++ b/source/blender/editors/space_image/image_undo.c @@ -1006,7 +1006,7 @@ void ED_image_undosys_type(UndoType *ut) * specific case, see `image_undosys_step_encode` code. We cannot specify * `UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE` though, as it can be called with a NULL context by * current code. */ - ut->flags = 0; + ut->flags = UNDOTYPE_FLAG_DECODE_ACTIVE_STEP; ut->step_size = sizeof(ImageUndoStep); } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index aaf9852e212..94e53958524 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -564,12 +564,11 @@ void FILE_OT_find_missing_files(wmOperatorType *ot) /** \name Report Box Operator * \{ */ -/* Hard to decide whether to keep this as an operator, - * or turn it into a hardcoded ui control feature, - * handling TIMER events for all regions in interface_handlers.c +/* NOTE(matt): Hard to decide whether to keep this as an operator, + * or turn it into a hard_coded UI control feature, + * handling TIMER events for all regions in `interface_handlers.c`. * Not sure how good that is to be accessing UI data from - * inactive regions, so use this for now. --matt - */ + * inactive regions, so use this for now. */ #define INFO_TIMEOUT 5.0f #define ERROR_TIMEOUT 10.0f diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index f2cea23af76..0498964c549 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -288,14 +288,14 @@ static int mouse_nla_channels( /* button region... */ if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) { if (nlaedit_is_tweakmode_on(ac) == 0) { - /* 'push-down' action - only usable when not in TweakMode */ + /* 'push-down' action - only usable when not in tweak-mode */ /* TODO: make this use the operator instead of calling the function directly * however, calling the operator requires that we supply the args, * and that works with proper buttons only */ BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ale->id)); } else { - /* when in tweakmode, this button becomes the toggle for mapped editing */ + /* When in tweak-mode, this button becomes the toggle for mapped editing. */ adt->flag ^= ADT_NLA_EDIT_NOMAP; } @@ -308,13 +308,13 @@ static int mouse_nla_channels( /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block * - this is useful when there's no clear divider, and makes more sense in * the case of users trying to use this to change actions - * - in tweakmode, clicking here gets us out of tweakmode, as changing selection - * while in tweakmode is really evil! + * - in tweak-mode, clicking here gets us out of tweak-mode, as changing selection + * while in tweak-mode is really evil! * - we disable "solo" flags too, to make it easier to work with stashed actions * with less trouble */ if (nlaedit_is_tweakmode_on(ac)) { - /* exit tweakmode immediately */ + /* Exit tweak-mode immediately. */ nlaedit_disable_tweakmode(ac, true); /* changes to NLA-Action occurred */ @@ -515,7 +515,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* 'push-down' action - only usable when not in TweakMode */ + /* 'push-down' action - only usable when not in Tweak-mode. */ BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(id)); struct Main *bmain = CTX_data_main(C); @@ -874,7 +874,7 @@ static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op)) /* operate on selected objects... */ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { /* ensure that object has AnimData... that's all */ - BKE_animdata_add_id(&ob->id); + BKE_animdata_ensure_id(&ob->id); } CTX_DATA_END; diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index ae86efc0e6a..56efcd8571f 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -135,7 +135,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ale->data; - /* try entering tweakmode if valid */ + /* Try entering tweak-mode if valid. */ ok |= BKE_nla_tweakmode_enter(adt); /* mark the active track as being "solo"? */ @@ -154,9 +154,8 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) ANIM_animdata_update(&ac, &anim_data); ANIM_animdata_freelist(&anim_data); - /* if we managed to enter tweakmode on at least one AnimData block, - * set the flag for this in the active scene and send notifiers - */ + /* If we managed to enter tweak-mode on at least one AnimData block, + * set the flag for this in the active scene and send notifiers. */ if (ac.scene && ok) { /* set editing flag */ ac.scene->flag |= SCE_NLA_EDIT_ON; @@ -206,7 +205,7 @@ void NLA_OT_tweakmode_enter(wmOperatorType *ot) /** \name Disable Tweak-Mode Operator * \{ */ -/* NLA Editor internal API function for exiting tweakmode */ +/* NLA Editor internal API function for exiting tweak-mode. */ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo) { ListBase anim_data = {NULL, NULL}; @@ -232,7 +231,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo) BKE_nlatrack_solo_toggle(adt, NULL); } - /* to be sure that we're doing everything right, just exit tweakmode... */ + /* To be sure that we're doing everything right, just exit tweak-mode. */ BKE_nla_tweakmode_exit(adt); ale->update |= ANIM_UPDATE_DEPS; @@ -242,7 +241,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo) ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); - /* if we managed to enter tweakmode on at least one AnimData block, + /* if we managed to enter tweak-mode on at least one AnimData block, * set the flag for this in the active scene and send notifiers */ if (ac->scene) { @@ -257,7 +256,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo) return true; } -/* exit tweakmode operator callback */ +/* Exit tweak-mode operator callback. */ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op) { bAnimContext ac; diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c index 631dc2e550c..28f194877fa 100644 --- a/source/blender/editors/space_nla/nla_ops.c +++ b/source/blender/editors/space_nla/nla_ops.c @@ -39,17 +39,16 @@ /* ************************** poll callbacks for operators **********************************/ -/* tweakmode is NOT enabled */ +/* Tweak-mode is NOT enabled. */ bool nlaop_poll_tweakmode_off(bContext *C) { Scene *scene; /* for now, we check 2 things: * 1) active editor must be NLA - * 2) tweakmode is currently set as a 'per-scene' flag + * 2) tweak-mode is currently set as a 'per-scene' flag * so that it will affect entire NLA data-sets, - * but not all AnimData blocks will be in tweakmode for - * various reasons + * but not all AnimData blocks will be in tweak-mode for various reasons. */ if (ED_operator_nla_active(C) == 0) { return 0; @@ -63,17 +62,16 @@ bool nlaop_poll_tweakmode_off(bContext *C) return 1; } -/* tweakmode IS enabled */ +/* Tweak-mode IS enabled. */ bool nlaop_poll_tweakmode_on(bContext *C) { Scene *scene; /* for now, we check 2 things: * 1) active editor must be NLA - * 2) tweakmode is currently set as a 'per-scene' flag + * 2) tweak-mode is currently set as a 'per-scene' flag * so that it will affect entire NLA data-sets, - * but not all AnimData blocks will be in tweakmode for - * various reasons + * but not all AnimData blocks will be in tweak-mode for various reasons. */ if (ED_operator_nla_active(C) == 0) { return 0; @@ -87,7 +85,7 @@ bool nlaop_poll_tweakmode_on(bContext *C) return 1; } -/* is tweakmode enabled - for use in NLA operator code */ +/* is tweak-mode enabled - for use in NLA operator code */ bool nlaedit_is_tweakmode_on(bAnimContext *ac) { if (ac && ac->scene) { diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c index dc95a01a021..246c3e0156a 100644 --- a/source/blender/editors/space_nla/nla_select.c +++ b/source/blender/editors/space_nla/nla_select.c @@ -453,7 +453,7 @@ static void nlaedit_select_leftright(bContext *C, Scene *scene = ac->scene; float xmin, xmax; - /* if currently in tweakmode, exit tweakmode first */ + /* if currently in tweak-mode, exit tweak-mode first */ if (scene->flag & SCE_NLA_EDIT_ON) { WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL); } @@ -612,7 +612,7 @@ static int mouse_nla_strips(bContext *C, nlaedit_strip_at_region_position(ac, mval[0], mval[1], &ale, &strip); - /* if currently in tweakmode, exit tweakmode before changing selection states + /* if currently in tweak-mode, exit tweak-mode before changing selection states * now that we've found our target... */ if (scene->flag & SCE_NLA_EDIT_ON) { diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 6e234c5b2ce..80d3b43bf6b 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../compositor ../../depsgraph ../../draw + ../../functions ../../gpu ../../imbuf ../../makesdna @@ -39,7 +40,6 @@ set(INC set(SRC drawnode.cc node_add.cc - node_buttons.c node_draw.cc node_edit.cc node_geometry_attribute_search.cc @@ -78,4 +78,20 @@ if(WITH_OPENSUBDIV) add_definitions(-DWITH_OPENSUBDIV) endif() +if(WITH_TBB) + add_definitions(-DWITH_TBB) + if(WIN32) + # TBB includes Windows.h which will define min/max macros + # that will collide with the stl versions. + add_definitions(-DNOMINMAX) + endif() + list(APPEND INC_SYS + ${TBB_INCLUDE_DIRS} + ) + + list(APPEND LIB + ${TBB_LIBRARIES} + ) +endif() + blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c deleted file mode 100644 index 336b0c46a81..00000000000 --- a/source/blender/editors/space_node/node_buttons.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup spnode - */ - -#include "MEM_guardedalloc.h" - -#include "DNA_node_types.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" - -#include "BLT_translation.h" - -#include "BKE_context.h" -#include "BKE_global.h" -#include "BKE_node.h" -#include "BKE_screen.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "RNA_access.h" - -#include "ED_screen.h" - -#include "UI_resources.h" - -#include "node_intern.h" /* own include */ - -/* ******************* node space & buttons ************** */ - -#if 0 -/* poll for active nodetree */ -static bool active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - - return (snode && snode->nodetree); -} -#endif - -static bool node_sockets_poll(const bContext *C, PanelType *UNUSED(pt)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - - return (snode && snode->nodetree && G.debug_value == 777); -} - -static void node_sockets_panel(const bContext *C, Panel *panel) -{ - SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */ - bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */ - bNode *node = nodeGetActive(ntree); - if (node == NULL) { - return; - } - - LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { - char name[UI_MAX_NAME_STR]; - BLI_snprintf(name, sizeof(name), "%s:", socket->name); - - uiLayout *split = uiLayoutSplit(panel->layout, 0.35f, false); - uiItemL(split, name, ICON_NONE); - uiTemplateNodeLink(split, (bContext *)C, ntree, node, socket); - } -} - -static bool node_tree_interface_poll(const bContext *C, PanelType *UNUSED(pt)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - - return (snode && snode->edittree && - (snode->edittree->inputs.first || snode->edittree->outputs.first)); -} - -static bNodeSocket *node_tree_find_active_socket(bNodeTree *ntree, const eNodeSocketInOut in_out) -{ - ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs; - LISTBASE_FOREACH (bNodeSocket *, socket, sockets) { - if (socket->flag & SELECT) { - return socket; - } - } - return NULL; -} - -static void draw_socket_list(const bContext *C, - uiLayout *layout, - bNodeTree *ntree, - const eNodeSocketInOut in_out) -{ - PointerRNA tree_ptr; - RNA_id_pointer_create((ID *)ntree, &tree_ptr); - - uiLayout *split = uiLayoutRow(layout, false); - uiLayout *list_col = uiLayoutColumn(split, true); - uiTemplateList(list_col, - (bContext *)C, - "NODE_UL_interface_sockets", - (in_out == SOCK_IN) ? "inputs" : "outputs", - &tree_ptr, - (in_out == SOCK_IN) ? "inputs" : "outputs", - &tree_ptr, - (in_out == SOCK_IN) ? "active_input" : "active_output", - NULL, - 0, - 0, - 0, - 0, - false, - false); - PointerRNA opptr; - uiLayout *ops_col = uiLayoutColumn(split, false); - uiLayout *add_remove_col = uiLayoutColumn(ops_col, true); - wmOperatorType *ot = WM_operatortype_find("NODE_OT_tree_socket_add", false); - uiItemFullO_ptr(add_remove_col, ot, "", ICON_ADD, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); - RNA_enum_set(&opptr, "in_out", in_out); - ot = WM_operatortype_find("NODE_OT_tree_socket_remove", false); - uiItemFullO_ptr(add_remove_col, ot, "", ICON_REMOVE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); - RNA_enum_set(&opptr, "in_out", in_out); - - uiItemS(ops_col); - - uiLayout *up_down_col = uiLayoutColumn(ops_col, true); - ot = WM_operatortype_find("NODE_OT_tree_socket_move", false); - uiItemFullO_ptr(up_down_col, ot, "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); - RNA_enum_set(&opptr, "direction", 1); - RNA_enum_set(&opptr, "in_out", in_out); - uiItemFullO_ptr(up_down_col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); - RNA_enum_set(&opptr, "direction", 2); - RNA_enum_set(&opptr, "in_out", in_out); - - bNodeSocket *socket = node_tree_find_active_socket(ntree, in_out); - if (socket != NULL) { - uiLayoutSetPropSep(layout, true); - uiLayoutSetPropDecorate(layout, false); - PointerRNA socket_ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, socket, &socket_ptr); - uiItemR(layout, &socket_ptr, "name", 0, NULL, ICON_NONE); - - /* Display descriptions only for Geometry Nodes, since it's only used in the modifier panel. */ - if (ntree->type == NTREE_GEOMETRY) { - uiItemR(layout, &socket_ptr, "description", 0, NULL, ICON_NONE); - } - - if (socket->typeinfo->interface_draw) { - socket->typeinfo->interface_draw((bContext *)C, layout, &socket_ptr); - } - } -} - -static void node_tree_interface_inputs_panel(const bContext *C, Panel *panel) -{ - SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */ - bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */ - - draw_socket_list(C, panel->layout, ntree, SOCK_IN); -} - -static void node_tree_interface_outputs_panel(const bContext *C, Panel *panel) -{ - SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */ - bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */ - - draw_socket_list(C, panel->layout, ntree, SOCK_OUT); -} - -/* ******************* node buttons registration ************** */ - -void node_buttons_register(ARegionType *art) -{ - { - PanelType *pt = MEM_callocN(sizeof(PanelType), __func__); - strcpy(pt->idname, "NODE_PT_sockets"); - strcpy(pt->category, N_("Node")); - strcpy(pt->label, N_("Sockets")); - strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = node_sockets_panel; - pt->poll = node_sockets_poll; - pt->flag |= PANEL_TYPE_DEFAULT_CLOSED; - BLI_addtail(&art->paneltypes, pt); - } - - { - PanelType *pt = MEM_callocN(sizeof(PanelType), __func__); - strcpy(pt->idname, "NODE_PT_node_tree_interface_inputs"); - strcpy(pt->category, N_("Group")); - strcpy(pt->label, N_("Inputs")); - strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = node_tree_interface_inputs_panel; - pt->poll = node_tree_interface_poll; - BLI_addtail(&art->paneltypes, pt); - } - { - PanelType *pt = MEM_callocN(sizeof(PanelType), __func__); - strcpy(pt->idname, "NODE_PT_node_tree_interface_outputs"); - strcpy(pt->category, N_("Group")); - strcpy(pt->label, N_("Outputs")); - strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = node_tree_interface_outputs_panel; - pt->poll = node_tree_interface_poll; - BLI_addtail(&art->paneltypes, pt); - } -} diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 8a341da0b5c..d4f178603b8 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -48,7 +48,6 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_node_ui_storage.hh" #include "BKE_object.h" #include "DEG_depsgraph.h" @@ -76,6 +75,8 @@ #include "RNA_access.h" +#include "NOD_geometry_nodes_eval_log.hh" + #include "node_intern.h" /* own include */ #ifdef WITH_COMPOSITOR @@ -86,6 +87,9 @@ using blender::Map; using blender::Set; using blender::Span; using blender::Vector; +using blender::fn::CPPType; +using blender::fn::GPointer; +namespace geo_log = blender::nodes::geometry_nodes_eval_log; extern "C" { /* XXX interface.h */ @@ -1185,14 +1189,14 @@ void node_draw_sockets(const View2D *v2d, } } -static int node_error_type_to_icon(const NodeWarningType type) +static int node_error_type_to_icon(const geo_log::NodeWarningType type) { switch (type) { - case NodeWarningType::Error: + case geo_log::NodeWarningType::Error: return ICON_ERROR; - case NodeWarningType::Warning: + case geo_log::NodeWarningType::Warning: return ICON_ERROR; - case NodeWarningType::Info: + case geo_log::NodeWarningType::Info: return ICON_INFO; } @@ -1200,14 +1204,14 @@ static int node_error_type_to_icon(const NodeWarningType type) return ICON_ERROR; } -static uint8_t node_error_type_priority(const NodeWarningType type) +static uint8_t node_error_type_priority(const geo_log::NodeWarningType type) { switch (type) { - case NodeWarningType::Error: + case geo_log::NodeWarningType::Error: return 3; - case NodeWarningType::Warning: + case geo_log::NodeWarningType::Warning: return 2; - case NodeWarningType::Info: + case geo_log::NodeWarningType::Info: return 1; } @@ -1215,11 +1219,11 @@ static uint8_t node_error_type_priority(const NodeWarningType type) return 0; } -static NodeWarningType node_error_highest_priority(Span<NodeWarning> warnings) +static geo_log::NodeWarningType node_error_highest_priority(Span<geo_log::NodeWarning> warnings) { uint8_t highest_priority = 0; - NodeWarningType highest_priority_type = NodeWarningType::Info; - for (const NodeWarning &warning : warnings) { + geo_log::NodeWarningType highest_priority_type = geo_log::NodeWarningType::Info; + for (const geo_log::NodeWarning &warning : warnings) { const uint8_t priority = node_error_type_priority(warning.type); if (priority > highest_priority) { highest_priority = priority; @@ -1229,15 +1233,17 @@ static NodeWarningType node_error_highest_priority(Span<NodeWarning> warnings) return highest_priority_type; } +struct NodeErrorsTooltipData { + Span<geo_log::NodeWarning> warnings; +}; + static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char *UNUSED(tip)) { - const NodeUIStorage **storage_pointer_alloc = static_cast<const NodeUIStorage **>(argN); - const NodeUIStorage *node_ui_storage = *storage_pointer_alloc; - Span<NodeWarning> warnings = node_ui_storage->warnings; + NodeErrorsTooltipData &data = *(NodeErrorsTooltipData *)argN; std::string complete_string; - for (const NodeWarning &warning : warnings.drop_back(1)) { + for (const geo_log::NodeWarning &warning : data.warnings.drop_back(1)) { complete_string += warning.message; /* Adding the period is not ideal for multi-line messages, but it is consistent * with other tooltip implementations in Blender, so it is added here. */ @@ -1246,7 +1252,7 @@ static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char } /* Let the tooltip system automatically add the last period. */ - complete_string += warnings.last().message; + complete_string += data.warnings.last().message; return BLI_strdupn(complete_string.c_str(), complete_string.size()); } @@ -1254,20 +1260,26 @@ static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char #define NODE_HEADER_ICON_SIZE (0.8f * U.widget_unit) static void node_add_error_message_button( - const bContext *C, bNodeTree &ntree, bNode &node, const rctf &rect, float &icon_offset) + const bContext *C, bNodeTree &UNUSED(ntree), bNode &node, const rctf &rect, float &icon_offset) { - const NodeUIStorage *node_ui_storage = BKE_node_tree_ui_storage_get_from_context(C, ntree, node); - if (node_ui_storage == nullptr || node_ui_storage->warnings.is_empty()) { + SpaceNode *snode = CTX_wm_space_node(C); + const geo_log::NodeLog *node_log = geo_log::ModifierLog::find_node_by_node_editor_context(*snode, + node); + if (node_log == nullptr) { + return; + } + + Span<geo_log::NodeWarning> warnings = node_log->warnings(); + + if (warnings.is_empty()) { return; } - /* The UI API forces us to allocate memory for each error button, because the - * ownership of #UI_but_func_tooltip_set's argument is transferred to the button. */ - const NodeUIStorage **storage_pointer_alloc = (const NodeUIStorage **)MEM_mallocN( - sizeof(NodeUIStorage *), __func__); - *storage_pointer_alloc = node_ui_storage; + NodeErrorsTooltipData *tooltip_data = (NodeErrorsTooltipData *)MEM_mallocN( + sizeof(NodeErrorsTooltipData), __func__); + tooltip_data->warnings = warnings; - const NodeWarningType display_type = node_error_highest_priority(node_ui_storage->warnings); + const geo_log::NodeWarningType display_type = node_error_highest_priority(warnings); icon_offset -= NODE_HEADER_ICON_SIZE; UI_block_emboss_set(node.block, UI_EMBOSS_NONE); @@ -1285,7 +1297,7 @@ static void node_add_error_message_button( 0, 0, nullptr); - UI_but_func_tooltip_set(but, node_errors_tooltip_fn, storage_pointer_alloc, MEM_freeN); + UI_but_func_tooltip_set(but, node_errors_tooltip_fn, tooltip_data, MEM_freeN); UI_block_emboss_set(node.block, UI_EMBOSS); } diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 9a6603eb589..5dd935bdd76 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2414,6 +2414,109 @@ void NODE_OT_tree_socket_remove(wmOperatorType *ot) RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", ""); } +/********************** Change interface socket type operator *********************/ + +static int ntree_socket_change_type_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out"); + const bNodeSocketType *socket_type = rna_node_socket_type_from_enum( + RNA_enum_get(op->ptr, "socket_type")); + ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs; + + Main *main = CTX_data_main(C); + + bNodeSocket *iosock = ntree_get_active_interface_socket(sockets); + if (iosock == nullptr) { + return OPERATOR_CANCELLED; + } + + /* The type remains the same, so we don't need to change anything. */ + if (iosock->typeinfo == socket_type) { + return OPERATOR_FINISHED; + } + + /* Don't handle subtypes for now. */ + nodeModifySocketType(ntree, nullptr, iosock, socket_type->idname); + + /* Need the extra update here because the loop above does not check for valid links in the node + * group we're currently editing. */ + ntree->update |= NTREE_UPDATE_GROUP | NTREE_UPDATE_LINKS; + + /* Deactivate sockets. */ + LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) { + socket_iter->flag &= ~SELECT; + } + /* Make the new socket active. */ + iosock->flag |= SELECT; + + ntreeUpdateTree(main, ntree); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr); + + return OPERATOR_FINISHED; +} + +static bool socket_change_poll_type(void *userdata, bNodeSocketType *socket_type) +{ + /* Check if the node tree supports the socket type. */ + bNodeTreeType *ntreetype = (bNodeTreeType *)userdata; + if (ntreetype->valid_socket_type && !ntreetype->valid_socket_type(ntreetype, socket_type)) { + return false; + } + + /* Only use basic socket types for this enum. */ + if (socket_type->subtype != PROP_NONE) { + return false; + } + + return true; +} + +static const EnumPropertyItem *socket_change_type_itemf(bContext *C, + PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), + bool *r_free) +{ + if (!C) { + return DummyRNA_NULL_items; + } + + SpaceNode *snode = CTX_wm_space_node(C); + if (!snode || !snode->edittree) { + return DummyRNA_NULL_items; + } + + return rna_node_socket_type_itemf(snode->edittree->typeinfo, socket_change_poll_type, r_free); +} + +void NODE_OT_tree_socket_change_type(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Change Node Tree Interface Socket Type"; + ot->description = "Change the type of a socket of the current node tree"; + ot->idname = "NODE_OT_tree_socket_change_type"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = ntree_socket_change_type_exec; + ot->poll = ED_operator_node_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", ""); + prop = RNA_def_enum(ot->srna, "socket_type", DummyRNA_DEFAULT_items, 0, "Socket Type", ""); + RNA_def_enum_funcs(prop, socket_change_type_itemf); + ot->prop = prop; +} + /********************** Move interface socket operator *********************/ static const EnumPropertyItem move_direction_items[] = { diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc index 94080a7b616..a6901c21862 100644 --- a/source/blender/editors/space_node/node_geometry_attribute_search.cc +++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc @@ -27,7 +27,6 @@ #include "DNA_space_types.h" #include "BKE_context.h" -#include "BKE_node_ui_storage.hh" #include "BKE_object.h" #include "RNA_access.h" @@ -40,17 +39,21 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "NOD_geometry_nodes_eval_log.hh" + #include "node_intern.h" using blender::IndexRange; using blender::Map; using blender::Set; using blender::StringRef; +namespace geo_log = blender::nodes::geometry_nodes_eval_log; +using geo_log::GeometryAttributeInfo; struct AttributeSearchData { - AvailableAttributeInfo &dummy_info_for_search; - const NodeUIStorage &ui_storage; - bNodeSocket &socket; + const bNodeTree *tree; + const bNode *node; + bNodeSocket *socket; }; /* This class must not have a destructor, since it is used by buttons and freed with #MEM_freeN. */ @@ -73,7 +76,7 @@ static StringRef attribute_domain_string(const AttributeDomain domain) /* Unicode arrow. */ #define MENU_SEP "\xe2\x96\xb6" -static bool attribute_search_item_add(uiSearchItems *items, const AvailableAttributeInfo &item) +static bool attribute_search_item_add(uiSearchItems *items, const GeometryAttributeInfo &item) { const StringRef data_type_name = attribute_data_type_string(item.data_type); const StringRef domain_name = attribute_domain_string(item.domain); @@ -84,31 +87,47 @@ static bool attribute_search_item_add(uiSearchItems *items, const AvailableAttri items, search_item_text.c_str(), (void *)&item, ICON_NONE, UI_BUT_HAS_SEP_CHAR, 0); } -static void attribute_search_update_fn(const bContext *UNUSED(C), - void *arg, - const char *str, - uiSearchItems *items, - const bool is_first) +static GeometryAttributeInfo &get_dummy_item_info() +{ + static GeometryAttributeInfo info; + return info; +} + +static void attribute_search_update_fn( + const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first) { AttributeSearchData *data = static_cast<AttributeSearchData *>(arg); - const Set<AvailableAttributeInfo> &attribute_hints = data->ui_storage.attribute_hints; + SpaceNode *snode = CTX_wm_space_node(C); + const geo_log::NodeLog *node_log = geo_log::ModifierLog::find_node_by_node_editor_context( + *snode, *data->node); + if (node_log == nullptr) { + return; + } + blender::Vector<const GeometryAttributeInfo *> infos = node_log->lookup_available_attributes(); + + GeometryAttributeInfo &dummy_info = get_dummy_item_info(); /* Any string may be valid, so add the current search string along with the hints. */ if (str[0] != '\0') { - /* Note that the attribute domain and data type are dummies, since - * #AvailableAttributeInfo equality is only based on the string. */ - if (!attribute_hints.contains(AvailableAttributeInfo{str, ATTR_DOMAIN_AUTO, CD_PROP_BOOL})) { - data->dummy_info_for_search.name = std::string(str); - UI_search_item_add(items, str, &data->dummy_info_for_search, ICON_ADD, 0, 0); + bool contained = false; + for (const GeometryAttributeInfo *attribute_info : infos) { + if (attribute_info->name == str) { + contained = true; + break; + } + } + if (!contained) { + dummy_info.name = str; + UI_search_item_add(items, str, &dummy_info, ICON_ADD, 0, 0); } } if (str[0] == '\0' && !is_first) { /* Allow clearing the text field when the string is empty, but not on the first pass, * or opening an attribute field for the first time would show this search item. */ - data->dummy_info_for_search.name = std::string(str); - UI_search_item_add(items, str, &data->dummy_info_for_search, ICON_X, 0, 0); + dummy_info.name = str; + UI_search_item_add(items, str, &dummy_info, ICON_X, 0, 0); } /* Don't filter when the menu is first opened, but still run the search @@ -116,15 +135,15 @@ static void attribute_search_update_fn(const bContext *UNUSED(C), const char *string = is_first ? "" : str; StringSearch *search = BLI_string_search_new(); - for (const AvailableAttributeInfo &item : attribute_hints) { - BLI_string_search_add(search, item.name.c_str(), (void *)&item); + for (const GeometryAttributeInfo *item : infos) { + BLI_string_search_add(search, item->name.c_str(), (void *)item); } - AvailableAttributeInfo **filtered_items; + GeometryAttributeInfo **filtered_items; const int filtered_amount = BLI_string_search_query(search, string, (void ***)&filtered_items); for (const int i : IndexRange(filtered_amount)) { - const AvailableAttributeInfo *item = filtered_items[i]; + const GeometryAttributeInfo *item = filtered_items[i]; if (!attribute_search_item_add(items, *item)) { break; } @@ -136,32 +155,25 @@ static void attribute_search_update_fn(const bContext *UNUSED(C), static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v) { + if (item_v == nullptr) { + return; + } AttributeSearchData *data = static_cast<AttributeSearchData *>(data_v); - AvailableAttributeInfo *item = static_cast<AvailableAttributeInfo *>(item_v); + GeometryAttributeInfo *item = (GeometryAttributeInfo *)item_v; - bNodeSocket &socket = data->socket; + bNodeSocket &socket = *data->socket; bNodeSocketValueString *value = static_cast<bNodeSocketValueString *>(socket.default_value); BLI_strncpy(value->value, item->name.c_str(), MAX_NAME); ED_undo_push(C, "Assign Attribute Name"); } -void node_geometry_add_attribute_search_button(const bContext *C, +void node_geometry_add_attribute_search_button(const bContext *UNUSED(C), const bNodeTree *node_tree, const bNode *node, PointerRNA *socket_ptr, uiLayout *layout) { - const NodeUIStorage *ui_storage = BKE_node_tree_ui_storage_get_from_context( - C, *node_tree, *node); - - if (ui_storage == nullptr) { - uiItemR(layout, socket_ptr, "default_value", 0, "", 0); - return; - } - - const NodeTreeUIStorage *tree_ui_storage = node_tree->ui_storage; - uiBlock *block = uiLayoutGetBlock(layout); uiBut *but = uiDefIconTextButR(block, UI_BTYPE_SEARCH_MENU, @@ -181,10 +193,8 @@ void node_geometry_add_attribute_search_button(const bContext *C, 0.0f, ""); - AttributeSearchData *data = OBJECT_GUARDED_NEW(AttributeSearchData, - {tree_ui_storage->dummy_info_for_search, - *ui_storage, - *static_cast<bNodeSocket *>(socket_ptr->data)}); + AttributeSearchData *data = OBJECT_GUARDED_NEW( + AttributeSearchData, {node_tree, node, (bNodeSocket *)socket_ptr->data}); UI_but_func_search_set_results_are_suggestions(but, true); UI_but_func_search_set_sep_string(but, MENU_SEP); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index e69f0cbea7f..09e5a110a45 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -140,9 +140,6 @@ void node_to_view(const struct bNode *node, float x, float y, float *rx, float * void node_to_updated_rect(const struct bNode *node, rctf *r_rect); void node_from_view(const struct bNode *node, float x, float y, float *rx, float *ry); -/* node_buttons.c */ -void node_buttons_register(struct ARegionType *art); - /* node_toolbar.c */ void node_toolbar_register(struct ARegionType *art); @@ -296,6 +293,7 @@ void NODE_OT_clipboard_paste(struct wmOperatorType *ot); void NODE_OT_tree_socket_add(struct wmOperatorType *ot); void NODE_OT_tree_socket_remove(struct wmOperatorType *ot); +void NODE_OT_tree_socket_change_type(struct wmOperatorType *ot); void NODE_OT_tree_socket_move(struct wmOperatorType *ot); void NODE_OT_shader_script_update(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index ce65fe93f20..610c2889e7a 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -119,6 +119,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_tree_socket_add); WM_operatortype_append(NODE_OT_tree_socket_remove); + WM_operatortype_append(NODE_OT_tree_socket_change_type); WM_operatortype_append(NODE_OT_tree_socket_move); WM_operatortype_append(NODE_OT_cryptomatte_layer_add); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index d7e16dd69f1..ff848a7bb95 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -651,6 +651,10 @@ static void node_main_region_init(wmWindowManager *wm, ARegion *region) lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW); WM_event_add_dropbox_handler(®ion->handlers, lb); + + /* The backdrop image gizmo needs to change together with the view. So always refresh gizmos on + * region size changes. */ + WM_gizmomap_tag_refresh(region->gizmo_map); } static void node_main_region_draw(const bContext *C, ARegion *region) @@ -1094,8 +1098,6 @@ void ED_spacetype_node(void) art->draw = node_buttons_region_draw; BLI_addhead(&st->regiontypes, art); - node_buttons_register(art); - /* regions: toolbar */ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region"); art->regionid = RGN_TYPE_TOOLS; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index d1fb36979b4..db37c8c1c8c 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2964,7 +2964,8 @@ static void outliner_draw_iconrow(bContext *C, te->flag &= ~(TE_ICONROW | TE_ICONROW_MERGED); /* object hierarchy always, further constrained on level */ - if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB))) { + if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) || + ELEM(tselem->type, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL)) { /* active blocks get white circle */ if (tselem->type == TSE_SOME_ID) { if (te->idcode == ID_OB) { diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh index f089a149805..96af8258010 100644 --- a/source/blender/editors/space_outliner/tree/tree_display.hh +++ b/source/blender/editors/space_outliner/tree/tree_display.hh @@ -86,7 +86,7 @@ class TreeDisplayViewLayer final : public AbstractTreeDisplay { ListBase buildTree(const TreeSourceData &source_data) override; private: - void add_view_layer(ListBase &, TreeElement &); + void add_view_layer(Scene &, ListBase &, TreeElement *); void add_layer_collections_recursive(ListBase &, ListBase &, TreeElement &); void add_layer_collection_objects(ListBase &, LayerCollection &, TreeElement &); void add_layer_collection_objects_children(TreeElement &); diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc index 3059f8bfe0c..a17bf174a74 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc @@ -150,27 +150,25 @@ TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar, } /* Create data-block list parent element on demand. */ - if (id != nullptr) { - TreeElement *ten; + TreeElement *ten; - if (filter_id_type) { - ten = tenlib; - } - else { - ten = outliner_add_element( - &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0); - ten->directdata = lbarray[a]; - ten->name = outliner_idcode_to_plural(GS(id->name)); - } + if (filter_id_type) { + ten = tenlib; + } + else { + ten = outliner_add_element( + &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0); + ten->directdata = lbarray[a]; + ten->name = outliner_idcode_to_plural(GS(id->name)); + } - for (ID *id : List<ID>(lbarray[a])) { - if (override_library_id_filter_poll(lib, id)) { - TreeElement *override_tree_element = outliner_add_element( - &space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0); + for (ID *id : List<ID>(lbarray[a])) { + if (override_library_id_filter_poll(lib, id)) { + TreeElement *override_tree_element = outliner_add_element( + &space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0); - if (BLI_listbase_is_empty(&override_tree_element->subtree)) { - outliner_free_tree_element(override_tree_element, &ten->subtree); - } + if (BLI_listbase_is_empty(&override_tree_element->subtree)) { + outliner_free_tree_element(override_tree_element, &ten->subtree); } } } diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc index 402526bbe8d..c3d0aecd3cb 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc @@ -70,74 +70,69 @@ TreeDisplayViewLayer::TreeDisplayViewLayer(SpaceOutliner &space_outliner) ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data) { ListBase tree = {nullptr}; - Scene *scene = source_data.scene; show_objects_ = !(space_outliner_.filter & SO_FILTER_NO_OBJECT); - const bool show_children = (space_outliner_.filter & SO_FILTER_NO_CHILDREN) == 0; - for (auto *view_layer : ListBaseWrapper<ViewLayer>(scene->view_layers)) { + view_layer_ = view_layer; + if (space_outliner_.filter & SO_FILTER_NO_VIEW_LAYERS) { if (view_layer != source_data.view_layer) { continue; } - } - TreeElement &te_view_layer = *outliner_add_element( - &space_outliner_, &tree, scene, nullptr, TSE_R_LAYER, 0); - TREESTORE(&te_view_layer)->flag &= ~TSE_CLOSED; - te_view_layer.name = view_layer->name; - te_view_layer.directdata = view_layer; - view_layer_ = view_layer; - - if (space_outliner_.filter & SO_FILTER_NO_COLLECTION) { - /* Show objects in the view layer. */ - for (Base *base : List<Base>(view_layer_->object_bases)) { - TreeElement *te_object = outliner_add_element(&space_outliner_, - &te_view_layer.subtree, - base->object, - &te_view_layer, - TSE_SOME_ID, - 0); - te_object->directdata = base; - } - - if (show_children) { - outliner_make_object_parent_hierarchy(&tree); - } + add_view_layer(*scene, tree, (TreeElement *)nullptr); } else { - /* Show collections in the view layer. */ - TreeElement &ten = *outliner_add_element(&space_outliner_, - &te_view_layer.subtree, - source_data.scene, - &te_view_layer, - TSE_VIEW_COLLECTION_BASE, - 0); - ten.name = IFACE_("Scene Collection"); - TREESTORE(&ten)->flag &= ~TSE_CLOSED; - - add_view_layer(ten.subtree, ten); - if (show_children) { - add_layer_collection_objects_children(ten); - } + TreeElement &te_view_layer = *outliner_add_element( + &space_outliner_, &tree, scene, nullptr, TSE_R_LAYER, 0); + TREESTORE(&te_view_layer)->flag &= ~TSE_CLOSED; + te_view_layer.name = view_layer->name; + te_view_layer.directdata = view_layer; + + add_view_layer(*scene, te_view_layer.subtree, &te_view_layer); } } return tree; } -void TreeDisplayViewLayer::add_view_layer(ListBase &tree, TreeElement &parent) +void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElement *parent) { - /* First layer collection is for master collection, don't show it. */ - LayerCollection *lc = static_cast<LayerCollection *>(view_layer_->layer_collections.first); - if (lc == nullptr) { - return; + const bool show_children = (space_outliner_.filter & SO_FILTER_NO_CHILDREN) == 0; + + if (space_outliner_.filter & SO_FILTER_NO_COLLECTION) { + /* Show objects in the view layer. */ + for (Base *base : List<Base>(view_layer_->object_bases)) { + TreeElement *te_object = outliner_add_element( + &space_outliner_, &tree, base->object, parent, TSE_SOME_ID, 0); + te_object->directdata = base; + } + + if (show_children) { + outliner_make_object_parent_hierarchy(&tree); + } } + else { + /* Show collections in the view layer. */ + TreeElement &ten = *outliner_add_element( + &space_outliner_, &tree, &scene, parent, TSE_VIEW_COLLECTION_BASE, 0); + ten.name = IFACE_("Scene Collection"); + TREESTORE(&ten)->flag &= ~TSE_CLOSED; + + /* First layer collection is for master collection, don't show it. */ + LayerCollection *lc = static_cast<LayerCollection *>(view_layer_->layer_collections.first); + if (lc == nullptr) { + return; + } - add_layer_collections_recursive(tree, lc->layer_collections, parent); - if (show_objects_) { - add_layer_collection_objects(tree, *lc, parent); + add_layer_collections_recursive(ten.subtree, lc->layer_collections, ten); + if (show_objects_) { + add_layer_collection_objects(ten.subtree, *lc, ten); + } + if (show_children) { + add_layer_collection_objects_children(ten); + } } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 9669ca2d7c2..8371a634a78 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -2479,10 +2479,12 @@ void draw_timeline_seq_display(const bContext *C, ARegion *region) const SpaceSeq *sseq = CTX_wm_space_seq(C); View2D *v2d = ®ion->v2d; - if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) { + if (scene->ed != NULL) { UI_view2d_view_ortho(v2d); draw_cache_view(C); - draw_overlap_frame_indicator(scene, v2d); + if (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) { + draw_overlap_frame_indicator(scene, v2d); + } UI_view2d_view_restore(C); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 45c6931364d..75cf8542f67 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2414,6 +2414,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) (LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN)); seqbase_clipboard_frame = scene->r.cfra; + SEQ_clipboard_active_seq_name_store(scene); /* Remove anything that references the current scene. */ LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { @@ -2504,6 +2505,10 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) BLI_movelisttolist(ed->seqbasep, &nseqbase); for (iseq = iseq_first; iseq; iseq = iseq->next) { + if (SEQ_clipboard_pasted_seq_was_active(iseq)) { + SEQ_select_active_set(scene, iseq); + } + /* Make sure, that pasted strips have unique names. */ SEQ_ensure_unique_name(iseq, scene); /* Translate after name has been changed, otherwise this will affect animdata of original diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c index 8cc8b4a007b..5d857f62b47 100644 --- a/source/blender/editors/space_sequencer/sequencer_scopes.c +++ b/source/blender/editors/space_sequencer/sequencer_scopes.c @@ -624,8 +624,6 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i { float rgb[3], yuv[3]; char *p; - int x = 0; - int y = 0; rgb[0] = (float)r / 255.0f; rgb[1] = (float)g / 255.0f; @@ -638,8 +636,8 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i r = 255; } - for (y = -size; y <= size; y++) { - for (x = -size; x <= size; x++) { + for (int y = -size; y <= size; y++) { + for (int x = -size; x <= size; x++) { char *q = p + 4 * (y * w + x); q[0] = r; q[1] = g; diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt index 1ea6593588a..e903feeec1b 100644 --- a/source/blender/editors/space_spreadsheet/CMakeLists.txt +++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt @@ -27,6 +27,7 @@ set(INC ../../gpu ../../makesdna ../../makesrna + ../../nodes ../../windowmanager ../../../../intern/glew-mx ../../../../intern/guardedalloc @@ -34,8 +35,8 @@ set(INC set(SRC space_spreadsheet.cc - spreadsheet_context.cc spreadsheet_column.cc + spreadsheet_context.cc spreadsheet_data_source.cc spreadsheet_data_source_geometry.cc spreadsheet_dataset_draw.cc @@ -46,10 +47,10 @@ set(SRC spreadsheet_row_filter.cc spreadsheet_row_filter_ui.cc - spreadsheet_context.hh spreadsheet_cell_value.hh spreadsheet_column.hh spreadsheet_column_values.hh + spreadsheet_context.hh spreadsheet_data_source.hh spreadsheet_data_source_geometry.hh spreadsheet_dataset_draw.hh 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 e42f70611c4..e38c70afd0f 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -31,11 +31,15 @@ #include "ED_spreadsheet.h" +#include "NOD_geometry_nodes_eval_log.hh" + #include "bmesh.h" #include "spreadsheet_data_source_geometry.hh" #include "spreadsheet_intern.hh" +namespace geo_log = blender::nodes::geometry_nodes_eval_log; + namespace blender::ed::spreadsheet { void GeometryDataSource::foreach_default_column_ids( @@ -436,13 +440,18 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread } } else { - if (object_eval->runtime.geometry_set_previews != nullptr) { - GHash *ghash = (GHash *)object_eval->runtime.geometry_set_previews; - const uint64_t key = ED_spreadsheet_context_path_hash(sspreadsheet); - GeometrySet *geometry_set_preview = (GeometrySet *)BLI_ghash_lookup_default( - ghash, POINTER_FROM_UINT(key), nullptr); - if (geometry_set_preview != nullptr) { - geometry_set = *geometry_set_preview; + const geo_log::NodeLog *node_log = + geo_log::ModifierLog::find_node_by_spreadsheet_editor_context(*sspreadsheet); + if (node_log != nullptr) { + for (const geo_log::SocketLog &input_log : node_log->input_logs()) { + if (const geo_log::GeometryValueLog *geo_value_log = + dynamic_cast<const geo_log::GeometryValueLog *>(input_log.value())) { + const GeometrySet *full_geometry = geo_value_log->full_geometry(); + if (full_geometry != nullptr) { + geometry_set = *full_geometry; + break; + } + } } } } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc index 5b5c5ed0b04..abbad8c7088 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc @@ -38,9 +38,9 @@ namespace blender::ed::spreadsheet { * Definition for the component->attribute-domain hierarchy. * Constructed at compile time. * - * \warning: Order of attribute-domains matters! It __must__ match the #AttributeDomain definition - * and fill gaps with unset optionals (i.e. `std::nullopt`). Would be nice to use array - * designators for this (which C++ doesn't support). + * \warning Order of attribute-domains matters! It __must__ match the #AttributeDomain + * definition and fill gaps with unset optionals (i.e. `std::nullopt`). Would be nice to use + * array designators for this (which C++ doesn't support). */ constexpr DatasetComponentLayoutInfo DATASET_layout_hierarchy[] = { { diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c index f55db8c3cc9..80af7d8c9f6 100644 --- a/source/blender/editors/space_text/text_undo.c +++ b/source/blender/editors/space_text/text_undo.c @@ -265,7 +265,7 @@ void ED_text_undosys_type(UndoType *ut) ut->step_foreach_ID_ref = text_undosys_foreach_ID_ref; - ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE; + ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE | UNDOTYPE_FLAG_DECODE_ACTIVE_STEP; ut->step_size = sizeof(TextUndoStep); } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index d5e52785937..3428a738dde 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -39,6 +39,8 @@ #include "BLT_translation.h" +#include "BLI_array_utils.h" +#include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -112,10 +114,94 @@ typedef struct { float ob_dims[3]; /* Floats only (treated as an array). */ TransformMedian ve_median, median; + bool tag_for_update; } TransformProperties; #define TRANSFORM_MEDIAN_ARRAY_LEN (sizeof(TransformMedian) / sizeof(float)) +static TransformProperties *v3d_transform_props_ensure(View3D *v3d); + +/* -------------------------------------------------------------------- */ +/** \name Edit Mesh Partial Updates + * \{ */ + +static void *editmesh_partial_update_begin_fn(struct bContext *UNUSED(C), + const struct uiBlockInteraction_Params *params, + void *arg1) +{ + const int retval_test = B_TRANSFORM_PANEL_MEDIAN; + if (BLI_array_findindex( + params->unique_retval_ids, params->unique_retval_ids_len, &retval_test) == -1) { + return NULL; + } + + BMEditMesh *em = arg1; + + int verts_mask_count = 0; + BMIter iter; + BMVert *eve; + int i; + + BLI_bitmap *verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__); + BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) { + if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + continue; + } + BLI_BITMAP_ENABLE(verts_mask, i); + verts_mask_count += 1; + } + + BMPartialUpdate *bmpinfo = BM_mesh_partial_create_from_verts_group_single( + em->bm, + &(BMPartialUpdate_Params){ + .do_tessellate = true, + .do_normals = true, + }, + verts_mask, + verts_mask_count); + + MEM_freeN(verts_mask); + + return bmpinfo; +} + +static void editmesh_partial_update_end_fn(struct bContext *UNUSED(C), + const struct uiBlockInteraction_Params *UNUSED(params), + void *UNUSED(arg1), + void *user_data) +{ + BMPartialUpdate *bmpinfo = user_data; + if (bmpinfo == NULL) { + return; + } + BM_mesh_partial_destroy(bmpinfo); +} + +static void editmesh_partial_update_update_fn( + struct bContext *C, + const struct uiBlockInteraction_Params *UNUSED(params), + void *arg1, + void *user_data) +{ + BMPartialUpdate *bmpinfo = user_data; + if (bmpinfo == NULL) { + return; + } + + View3D *v3d = CTX_wm_view3d(C); + TransformProperties *tfp = v3d_transform_props_ensure(v3d); + if (tfp->tag_for_update == false) { + return; + } + tfp->tag_for_update = false; + + BMEditMesh *em = arg1; + + BKE_editmesh_looptri_and_normals_calc_with_partial(em, bmpinfo); +} + +/** \} */ + /* Helper function to compute a median changed value, * when the value should be clamped in [0.0, 1.0]. * Returns either 0.0, 1.0 (both can be applied directly), a positive scale factor @@ -840,6 +926,20 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } UI_block_align_end(block); + + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + BMEditMesh *em = me->edit_mesh; + if (em != NULL) { + UI_block_interaction_set(block, + &(uiBlockInteraction_CallbackData){ + .begin_fn = editmesh_partial_update_begin_fn, + .end_fn = editmesh_partial_update_end_fn, + .update_fn = editmesh_partial_update_update_fn, + .arg1 = em, + }); + } + } } else { /* apply */ memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median)); @@ -927,9 +1027,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } if (apply_vcos) { - /* TODO: use the #BKE_editmesh_looptri_and_normals_calc_with_partial - * This requires begin/end states for UI interaction (which currently aren't supported). */ - BKE_editmesh_looptri_and_normals_calc(em); + /* Tell the update callback to run. */ + tfp->tag_for_update = true; } /* Edges */ @@ -1152,7 +1251,7 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event) ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = view_layer->basact->object; ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE); - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); } @@ -1466,7 +1565,7 @@ static void v3d_posearmature_buts(uiLayout *layout, Object *ob) /* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.) * but old-school UI shows in eulers always. Do we want to be able to still display in Eulers? - * Maybe needs RNA/ui options to display rotations as different types... */ + * Maybe needs RNA/UI options to display rotations as different types. */ v3d_transform_butsR(col, &pchanptr); } @@ -1570,7 +1669,7 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event case B_TRANSFORM_PANEL_MEDIAN: if (ob) { v3d_editvertex_buts(NULL, v3d, ob, 1.0); - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY); } break; case B_TRANSFORM_PANEL_DIMS: diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ea9d9a8c010..c97ba7ba7e9 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1404,7 +1404,7 @@ static void draw_selected_name( /* color depends on whether there is a keyframe */ if (id_frame_has_keyframe( - (ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) { + (ID *)ob, /* BKE_scene_ctime_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) { UI_FontThemeColor(font_id, TH_TIME_KEYFRAME); } else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra)) { diff --git a/source/blender/editors/space_view3d/view3d_navigate_fly.c b/source/blender/editors/space_view3d/view3d_navigate_fly.c index e2fa0fdc6a5..5752837c40f 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_fly.c +++ b/source/blender/editors/space_view3d/view3d_navigate_fly.c @@ -122,7 +122,7 @@ void fly_modal_keymap(wmKeyConfig *keyconf) {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""}, {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"}, - {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"}, + {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "Z Axis Correction", "Z axis correction (toggle)"}, {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision", ""}, {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision (Off)", ""}, diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c index 435d74aa591..09936b41a74 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_walk.c +++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c @@ -98,9 +98,10 @@ enum { WALK_MODAL_JUMP, WALK_MODAL_JUMP_STOP, WALK_MODAL_TELEPORT, - WALK_MODAL_TOGGLE, + WALK_MODAL_GRAVITY_TOGGLE, WALK_MODAL_ACCELERATE, WALK_MODAL_DECELERATE, + WALK_MODAL_AXIS_LOCK_Z, }; enum { @@ -129,6 +130,18 @@ typedef enum eWalkGravityState { WALK_GRAVITY_STATE_ON, } eWalkGravityState; +/* Relative view axis z axis locking. */ +typedef enum eWalkLockState { + /* Disabled. */ + WALK_AXISLOCK_STATE_OFF = 0, + + /* Moving. */ + WALK_AXISLOCK_STATE_ACTIVE = 2, + + /* Done moving, it cannot be activated again. */ + WALK_AXISLOCK_STATE_DONE = 3, +} eWalkLockState; + /* Called in transform_ops.c, on each regeneration of key-maps. */ void walk_modal_keymap(wmKeyConfig *keyconf) { @@ -164,7 +177,9 @@ void walk_modal_keymap(wmKeyConfig *keyconf) {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"}, {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump (Off)", "Stop pushing jump"}, - {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"}, + {WALK_MODAL_GRAVITY_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"}, + + {WALK_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "Z Axis Correction", "Z axis correction"}, {0, NULL, 0, NULL, NULL}, }; @@ -292,6 +307,10 @@ typedef struct WalkInfo { /** To use for fast/slow speeds. */ float speed_factor; + eWalkLockState zlock; + /** Nicer dynamics. */ + float zlock_momentum; + struct SnapObjectContext *snap_context; struct View3DCameraControl *v3d_camera_control; @@ -540,6 +559,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) walk->jump_height = U.walk_navigation.jump_height; walk->speed = U.walk_navigation.walk_speed; walk->speed_factor = U.walk_navigation.walk_speed_factor; + walk->zlock = WALK_AXISLOCK_STATE_OFF; walk->gravity_state = WALK_GRAVITY_STATE_OFF; @@ -708,8 +728,6 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event) walk->is_cursor_absolute = true; copy_v2_v2_int(walk->prev_mval, event->mval); copy_v2_v2_int(walk->center_mval, event->mval); - /* Without this we can't turn 180d with the default speed of 1.0. */ - walk->mouse_speed *= 4.0f; } #endif /* USE_TABLET_SUPPORT */ @@ -941,7 +959,7 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event) #undef JUMP_TIME_MAX #undef JUMP_SPEED_MIN - case WALK_MODAL_TOGGLE: + case WALK_MODAL_GRAVITY_TOGGLE: if (walk->navigation_mode == WALK_MODE_GRAVITY) { walk_navigation_mode_set(walk, WALK_MODE_FREE); } @@ -949,6 +967,13 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event) walk_navigation_mode_set(walk, WALK_MODE_GRAVITY); } break; + + case WALK_MODAL_AXIS_LOCK_Z: + if (walk->zlock != WALK_AXISLOCK_STATE_DONE) { + walk->zlock = WALK_AXISLOCK_STATE_ACTIVE; + walk->zlock_momentum = 0.0f; + } + break; } } } @@ -982,12 +1007,14 @@ static float getVelocityZeroTime(const float gravity, const float velocity) static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) { -#define WALK_ROTATE_RELATIVE_FAC 2.2f /* More is faster, relative to region size. */ -#define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* More is faster, radians per-pixel. */ +#define WALK_ROTATE_TABLET_FAC 8.8f /* Higher is faster, relative to region size. */ +#define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* Higher is faster, radians per-pixel. */ #define WALK_TOP_LIMIT DEG2RADF(85.0f) #define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f) #define WALK_MOVE_SPEED base_speed #define WALK_BOOST_FACTOR ((void)0, walk->speed_factor) +#define WALK_ZUP_CORRECT_FAC 0.1f /* Amount to correct per step. */ +#define WALK_ZUP_CORRECT_ACCEL 0.05f /* Increase upright momentum each step. */ RegionView3D *rv3d = walk->rv3d; ARegion *region = walk->region; @@ -1022,20 +1049,25 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) /* Should we redraw? */ if ((walk->active_directions) || moffset[0] || moffset[1] || - walk->teleport.state == WALK_TELEPORT_STATE_ON || - walk->gravity_state != WALK_GRAVITY_STATE_OFF || is_confirm) { + walk->zlock == WALK_AXISLOCK_STATE_ACTIVE || + walk->gravity_state != WALK_GRAVITY_STATE_OFF || + walk->teleport.state == WALK_TELEPORT_STATE_ON || is_confirm) { float dvec_tmp[3]; /* time how fast it takes for us to redraw, * this is so simple scenes don't walk too fast */ double time_current; float time_redraw; + float time_redraw_clamped; #ifdef NDOF_WALK_DRAW_TOOMUCH walk->redraw = 1; #endif time_current = PIL_check_seconds_timer(); time_redraw = (float)(time_current - walk->time_lastdraw); + /* Clamp redraw time to avoid jitter in roll correction. */ + time_redraw_clamped = min_ff(0.05f, time_redraw); + walk->time_lastdraw = time_current; /* base speed in m/s */ @@ -1064,7 +1096,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) #ifdef USE_TABLET_SUPPORT if (walk->is_cursor_absolute) { y /= region->winy; - y *= WALK_ROTATE_RELATIVE_FAC; + y *= WALK_ROTATE_TABLET_FAC; } else #endif @@ -1113,7 +1145,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) #ifdef USE_TABLET_SUPPORT if (walk->is_cursor_absolute) { x /= region->winx; - x *= WALK_ROTATE_RELATIVE_FAC; + x *= WALK_ROTATE_TABLET_FAC; } else #endif @@ -1128,6 +1160,32 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) axis_angle_to_quat_single(tmp_quat, 'Z', x); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); } + + if (walk->zlock == WALK_AXISLOCK_STATE_ACTIVE) { + float upvec[3]; + copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); + mul_m3_v3(mat, upvec); + + /* Make sure we have some z rolling. */ + if (fabsf(upvec[2]) > 0.00001f) { + float roll = upvec[2] * 5.0f; + /* Rotate the view about this axis. */ + copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f); + mul_m3_v3(mat, upvec); + /* Rotate about the relative up vec. */ + axis_angle_to_quat(tmp_quat, + upvec, + roll * time_redraw_clamped * walk->zlock_momentum * + WALK_ZUP_CORRECT_FAC); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + walk->zlock_momentum += WALK_ZUP_CORRECT_ACCEL; + } + else { + /* Lock fixed, don't need to check it ever again. */ + walk->zlock = WALK_AXISLOCK_STATE_DONE; + } + } } /* WASD - 'move' translation code */ @@ -1318,7 +1376,8 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) add_v3_v3(rv3d->ofs, dvec_tmp); if (rv3d->persp == RV3D_CAMOB) { - walk->need_rotation_keyframe |= (moffset[0] || moffset[1]); + walk->need_rotation_keyframe |= (moffset[0] || moffset[1] || + walk->zlock == WALK_AXISLOCK_STATE_ACTIVE); walk->need_translation_keyframe |= (len_squared_v3(dvec_tmp) > FLT_EPSILON); walkMoveCamera( C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm); @@ -1333,7 +1392,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm) } return OPERATOR_FINISHED; -#undef WALK_ROTATE_RELATIVE_FAC +#undef WALK_ROTATE_TABLET_FAC #undef WALK_TOP_LIMIT #undef WALK_BOTTOM_LIMIT #undef WALK_MOVE_SPEED diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index a19e92f229a..4482e5897ca 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -511,47 +511,47 @@ static int snap_selected_to_location(bContext *C, for (int ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; + if (ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) { + continue; + } - if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) { - - float cursor_parent[3]; /* parent-relative */ - - if (use_offset) { - add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global); - } - else { - copy_v3_v3(cursor_parent, snap_target_global); - } + float cursor_parent[3]; /* parent-relative */ - sub_v3_v3(cursor_parent, ob->obmat[3]); + if (use_offset) { + add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global); + } + else { + copy_v3_v3(cursor_parent, snap_target_global); + } - if (ob->parent) { - float originmat[3][3], parentmat[4][4]; - /* Use the evaluated object here because sometimes - * `ob->parent->runtime.curve_cache` is required. */ - BKE_scene_graph_evaluated_ensure(depsgraph, bmain); - Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + sub_v3_v3(cursor_parent, ob->obmat[3]); - BKE_object_get_parent_matrix(ob_eval, ob_eval->parent, parentmat); - mul_m3_m4m4(originmat, parentmat, ob->parentinv); - invert_m3_m3(imat, originmat); - mul_m3_v3(imat, cursor_parent); - } - if ((ob->protectflag & OB_LOCK_LOCX) == 0) { - ob->loc[0] += cursor_parent[0]; - } - if ((ob->protectflag & OB_LOCK_LOCY) == 0) { - ob->loc[1] += cursor_parent[1]; - } - if ((ob->protectflag & OB_LOCK_LOCZ) == 0) { - ob->loc[2] += cursor_parent[2]; - } + if (ob->parent) { + float originmat[3][3], parentmat[4][4]; + /* Use the evaluated object here because sometimes + * `ob->parent->runtime.curve_cache` is required. */ + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + + BKE_object_get_parent_matrix(ob_eval, ob_eval->parent, parentmat); + mul_m3_m4m4(originmat, parentmat, ob->parentinv); + invert_m3_m3(imat, originmat); + mul_m3_v3(imat, cursor_parent); + } + if ((ob->protectflag & OB_LOCK_LOCX) == 0) { + ob->loc[0] += cursor_parent[0]; + } + if ((ob->protectflag & OB_LOCK_LOCY) == 0) { + ob->loc[1] += cursor_parent[1]; + } + if ((ob->protectflag & OB_LOCK_LOCZ) == 0) { + ob->loc[2] += cursor_parent[2]; + } - /* auto-keyframing */ - ED_autokeyframe_object(C, scene, ob, ks); + /* auto-keyframing */ + ED_autokeyframe_object(C, scene, ob, ks); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); - } + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); } if (objects) { diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index c1ee6edfef6..18cd62a0baf 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -2094,7 +2094,7 @@ void recalcData_mesh(TransInfo *t) tc_mesh_partial_types_calc(t, &partial_state); FOREACH_TRANS_DATA_CONTAINER (t, tc) { - DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY_DEFORM); tc_mesh_partial_update(t, tc, &partial_state); } diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c index 3b1191a3401..2db3e259153 100644 --- a/source/blender/editors/transform/transform_convert_mesh_edge.c +++ b/source/blender/editors/transform/transform_convert_mesh_edge.c @@ -28,6 +28,7 @@ #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_mesh.h" diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c index d91a2a8be4b..61397b6ef4b 100644 --- a/source/blender/editors/transform/transform_convert_mesh_uv.c +++ b/source/blender/editors/transform/transform_convert_mesh_uv.c @@ -30,6 +30,7 @@ #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_mesh_mapping.h" diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index c217478bd04..ee6cb391fdc 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -153,7 +153,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) if (t->mode != TFM_DUMMY && ob->rigidbody_object) { float rot[3][3], scale[3]; - float ctime = BKE_scene_frame_get(scene); + float ctime = BKE_scene_ctime_get(scene); /* only use rigid body transform if simulation is running, * avoids problems with initial setup of rigid bodies */ @@ -978,7 +978,7 @@ void special_aftertrans_update__object(bContext *C, TransInfo *t) /* restore rigid body transform */ if (ob->rigidbody_object && canceled) { - float ctime = BKE_scene_frame_get(t->scene); + float ctime = BKE_scene_ctime_get(t->scene); if (BKE_rigidbody_check_sim_running(t->scene->rigidbody_world, ctime)) { BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 8a4c8f410c0..2d98d756dba 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -535,7 +535,7 @@ static void iter_snap_objects(SnapObjectContext *sctx, * \{ */ /* Store all ray-hits - * Support for storing all depths, not just the first (raycast 'all') */ + * Support for storing all depths, not just the first (ray-cast 'all'). */ struct RayCastAll_Data { void *bvhdata; @@ -626,7 +626,7 @@ static bool raycast_tri_backface_culling_test( return dot_v3v3(no, dir) < 0.0f; } -/* Callback to raycast with backface culling (Mesh). */ +/* Callback to ray-cast with back-face culling (#Mesh). */ static void mesh_looptri_raycast_backface_culling_cb(void *userdata, int index, const BVHTreeRay *ray, @@ -653,7 +653,7 @@ static void mesh_looptri_raycast_backface_culling_cb(void *userdata, } } -/* Callback to raycast with backface culling (EditMesh). */ +/* Callback to ray-cast with back-face culling (#EditMesh). */ static void editmesh_looptri_raycast_backface_culling_cb(void *userdata, int index, const BVHTreeRay *ray, diff --git a/source/blender/editors/uvedit/uvedit_islands.c b/source/blender/editors/uvedit/uvedit_islands.c index 93948b5ae1b..56bcbc63de1 100644 --- a/source/blender/editors/uvedit/uvedit_islands.c +++ b/source/blender/editors/uvedit/uvedit_islands.c @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_rect.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "DEG_depsgraph.h" diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index eb4ca2e13b2..f97403a0919 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -2154,7 +2154,7 @@ static void p_collapse_cost_vertex(PVert *vert, float *r_mincost, PEdge **r_mine static void p_chart_post_collapse_flush(PChart *chart, PEdge *collapsed) { - /* move to collapsed_ */ + /* Move to `collapsed_*`. */ PVert *v, *nextv = NULL, *verts = chart->verts; PEdge *e, *nexte = NULL, *edges = chart->edges, *laste = NULL; @@ -2224,7 +2224,7 @@ static void p_chart_post_collapse_flush(PChart *chart, PEdge *collapsed) static void p_chart_post_split_flush(PChart *chart) { - /* move from collapsed_ */ + /* Move from `collapsed_*`. */ PVert *v, *nextv = NULL; PEdge *e, *nexte = NULL; @@ -2259,7 +2259,7 @@ static void p_chart_post_split_flush(PChart *chart) static void p_chart_simplify_compute(PChart *chart) { /* Computes a list of edge collapses / vertex splits. The collapsed - * simplices go in the chart->collapsed_* lists, The original and + * simplices go in the `chart->collapsed_*` lists, The original and * collapsed may then be view as stacks, where the next collapse/split * is at the top of the respective lists. */ diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h index 209ec86edef..cc4c0749ca8 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.h +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -514,7 +514,7 @@ class Stroke : public Interface1D { return _id; } - /** The different blending modes available to similate the interaction media-medium. */ + /** The different blending modes available to simulate the interaction media-medium. */ typedef enum { DRY_MEDIUM, /**< To simulate a dry medium such as Pencil or Charcoal. */ HUMID_MEDIUM, /**< To simulate ink painting (color subtraction blending). */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index 9593a1364e7..fcc44aab583 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -205,11 +205,18 @@ static void bakeModifier(Main *UNUSED(bmain), } if (!gpd->runtime.lineart_cache) { + /* Only calculate for this modifier, thus no need to get maximum values from all line art + * modifiers in the stack. */ + lmd->edge_types_override = lmd->edge_types; + lmd->level_end_override = lmd->level_end; + MOD_lineart_compute_feature_lines(depsgraph, lmd, &gpd->runtime.lineart_cache); MOD_lineart_destroy_render_data(lmd); } generate_strokes_actual(md, depsgraph, ob, gpl, gpf); + + MOD_lineart_clear_cache(&gpd->runtime.lineart_cache); } static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) @@ -331,7 +338,7 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel) PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr); const bool is_baked = RNA_boolean_get(ptr, "is_baked"); - const bool use_cache = RNA_boolean_get(ptr, "use_cached_result"); + const bool use_cache = RNA_boolean_get(ptr, "use_cache"); const bool is_first = BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data); uiLayoutSetEnabled(layout, !is_baked); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index ce6242ec272..cddf3b7cfb5 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -1696,7 +1696,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu } if (rb->remove_doubles) { - BMEditMesh *em = BKE_editmesh_create(bm, false); + BMEditMesh *em = BKE_editmesh_create(bm); BMOperator findop, weldop; /* See bmesh_opdefines.c and bmesh_operators.c for op names and argument formatting. */ diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index abb7330d292..b7dc3210c41 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -82,8 +82,8 @@ set(SRC intern/gpu_select_sample_query.cc intern/gpu_shader.cc intern/gpu_shader_builtin.c - intern/gpu_shader_log.cc intern/gpu_shader_interface.cc + intern/gpu_shader_log.cc intern/gpu_state.cc intern/gpu_texture.cc intern/gpu_uniform_buffer.cc @@ -103,8 +103,8 @@ set(SRC opengl/gl_index_buffer.cc opengl/gl_query.cc opengl/gl_shader.cc - opengl/gl_shader_log.cc opengl/gl_shader_interface.cc + opengl/gl_shader_log.cc opengl/gl_state.cc opengl/gl_texture.cc opengl/gl_uniform_buffer.cc diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 1ae68d6813c..f90c37e5c50 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -365,8 +365,8 @@ static void detect_workarounds() (strstr(version, "Build 20.19.15.4285"))) { GCaps.use_main_context_workaround = true; } - /* See T70187: merging vertices fail. This has been tested from 18.2.2 till 19.3.0~dev of the - * Mesa driver */ + /* See T70187: merging vertices fail. This has been tested from `18.2.2` till `19.3.0~dev` + * of the Mesa driver */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") || strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2"))) { diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc index ac42a950945..3e259235515 100644 --- a/source/blender/gpu/opengl/gl_debug.cc +++ b/source/blender/gpu/opengl/gl_debug.cc @@ -81,9 +81,11 @@ static void APIENTRY debug_callback(GLenum UNUSED(source), return; } - if (TRIM_NVIDIA_BUFFER_INFO && - GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) && - STRPREFIX(message, "Buffer detailed info")) { + /* NOTE: callback function can be triggered during before the platform is initialized. + * In this case invoking `GPU_type_matches` would fail and + * therefore the message is checked before the platform matching. */ + if (TRIM_NVIDIA_BUFFER_INFO && STRPREFIX(message, "Buffer detailed info") && + GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) { /** Suppress buffer infos flooding the output. */ return; } diff --git a/source/blender/gpu/opengl/gl_drawlist.hh b/source/blender/gpu/opengl/gl_drawlist.hh index db4b9c03c3c..6f80fdd5a8a 100644 --- a/source/blender/gpu/opengl/gl_drawlist.hh +++ b/source/blender/gpu/opengl/gl_drawlist.hh @@ -72,7 +72,7 @@ class GLDrawList : public DrawList { GLuint buffer_id_; /** Length of whole the buffer (in byte). */ GLsizeiptr buffer_size_; - /** Offset of data_ inside the whole buffer (in byte). */ + /** Offset of `data_` inside the whole buffer (in byte). */ GLintptr data_offset_; /** To free the buffer_id_. */ diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c index ad72f373d12..70bb70ec4fa 100644 --- a/source/blender/imbuf/intern/bmp.c +++ b/source/blender/imbuf/intern/bmp.c @@ -395,9 +395,8 @@ bool imb_savebmp(ImBuf *ibuf, const char *filepath, int UNUSED(flags)) } } } - if (ofile) { - fflush(ofile); - fclose(ofile); - } + + fflush(ofile); + fclose(ofile); return 1; } diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h index 5664a43233a..3d1391ac2a4 100644 --- a/source/blender/io/alembic/ABC_alembic.h +++ b/source/blender/io/alembic/ABC_alembic.h @@ -19,6 +19,8 @@ * \ingroup balembic */ +#include "DEG_depsgraph.h" + #ifdef __cplusplus extern "C" { #endif @@ -54,7 +56,6 @@ struct AlembicExportParams { bool curves_as_mesh; bool flatten_hierarchy; bool visible_objects_only; - bool renderable_only; bool face_sets; bool use_subdiv_schema; bool packuv; @@ -63,6 +64,7 @@ struct AlembicExportParams { bool export_particles; bool export_custom_properties; bool use_instancing; + enum eEvaluationMode evaluation_mode; /* See MOD_TRIANGULATE_NGON_xxx and MOD_TRIANGULATE_QUAD_xxx * in DNA_modifier_types.h */ diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc index 5b8998a0b1a..efe04d64cc3 100644 --- a/source/blender/io/alembic/exporter/abc_export_capi.cc +++ b/source/blender/io/alembic/exporter/abc_export_capi.cc @@ -213,8 +213,7 @@ bool ABC_export(Scene *scene, job->export_ok = false; BLI_strncpy(job->filename, filepath, sizeof(job->filename)); - job->depsgraph = DEG_graph_new( - job->bmain, scene, view_layer, DAG_EVAL_RENDER /* TODO(Sybren): params->evaluation_mode */); + job->depsgraph = DEG_graph_new(job->bmain, scene, view_layer, params->evaluation_mode); job->params = *params; bool export_ok = false; diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.cc b/source/blender/io/alembic/exporter/abc_writer_abstract.cc index 27b5c2fa2a4..910e04f3bf5 100644 --- a/source/blender/io/alembic/exporter/abc_writer_abstract.cc +++ b/source/blender/io/alembic/exporter/abc_writer_abstract.cc @@ -137,7 +137,7 @@ void ABCAbstractWriter::update_bounding_box(Object *object) void ABCAbstractWriter::write_visibility(const HierarchyContext &context) { - const bool is_visible = context.is_object_visible(DAG_EVAL_RENDER); + const bool is_visible = context.is_object_visible(args_.export_params->evaluation_mode); Alembic::Abc::OObject abc_object = get_alembic_object(); if (!abc_visibility_.valid()) { diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index fd7db005dd2..7ffb61e1d1b 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -162,7 +162,7 @@ ModifierData *ABCGenericMeshWriter::get_liquid_sim_modifier(Scene *scene, Object bool ABCGenericMeshWriter::is_supported(const HierarchyContext *context) const { if (args_.export_params->visible_objects_only) { - return context->is_object_visible(DAG_EVAL_RENDER); + return context->is_object_visible(args_.export_params->evaluation_mode); } return true; } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index c9d652ad03d..43969bf0768 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -621,9 +621,9 @@ typedef enum IDRecalcFlag { * When a collection gets tagged with this flag, all objects depending on the geometry and * transforms on any of the objects in the collection are updated. */ ID_RECALC_GEOMETRY = (1 << 1), - - /* ** Animation or time changed and animation is to be re-evaluated. ** */ - ID_RECALC_ANIMATION = (1 << 2), + /* Same as #ID_RECALC_GEOMETRY, but instead of tagging the batch cache as `dirty_all`, just tags + what matches the deform cache. */ + ID_RECALC_GEOMETRY_DEFORM = (1 << 2), /* ** Particle system changed. ** */ /* Only do pathcache etc. */ @@ -683,6 +683,9 @@ typedef enum IDRecalcFlag { * have to be copied on every update. */ ID_RECALC_PARAMETERS = (1 << 21), + /* ** Animation or time changed and animation is to be re-evaluated. ** */ + ID_RECALC_ANIMATION = (1 << 22), + /* Input has changed and datablock is to be reload from disk. * Applies to movie clips to inform that copy-on-written version is to be refreshed for the new * input file or for color space changes. */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 08a38f0652c..1c765d19ce2 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -2256,6 +2256,10 @@ typedef struct NodesModifierData { ModifierData modifier; struct bNodeTree *node_group; struct NodesModifierSettings settings; + + /* Contains logged information from the last evaluation. This can be used to help the user to + * debug a node tree. */ + void *runtime_eval_log; } NodesModifierData; typedef struct MeshToVolumeModifierData { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 199b69d61c5..5e4692481ba 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -37,7 +37,6 @@ struct Collection; struct ID; struct Image; struct ListBase; -struct NodeTreeUIStorage; struct bGPdata; struct bNodeInstanceHash; struct bNodeLink; @@ -516,8 +515,6 @@ typedef struct bNodeTree { int (*test_break)(void *); void (*update_draw)(void *); void *tbh, *prh, *sdh, *udh; - - struct NodeTreeUIStorage *ui_storage; } bNodeTree; /* ntree->type, index */ @@ -1373,6 +1370,11 @@ typedef struct NodeGeometryCurvePrimitiveCircle { uint8_t mode; } NodeGeometryCurvePrimitiveCircle; +typedef struct NodeGeometryCurvePrimitiveQuad { + /* GeometryNodeCurvePrimitiveQuadMode. */ + uint8_t mode; +} NodeGeometryCurvePrimitiveQuad; + typedef struct NodeGeometryCurveResample { /* GeometryNodeCurveSampleMode. */ uint8_t mode; @@ -1923,6 +1925,14 @@ typedef enum GeometryNodeCurvePrimitiveLineMode { GEO_NODE_CURVE_PRIMITIVE_LINE_MODE_DIRECTION = 1 } GeometryNodeCurvePrimitiveLineMode; +typedef enum GeometryNodeCurvePrimitiveQuadMode { + GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE = 0, + GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_PARALLELOGRAM = 1, + GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_TRAPEZOID = 2, + GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_KITE = 3, + GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_POINTS = 4, +} GeometryNodeCurvePrimitiveQuadMode; + typedef enum GeometryNodeCurvePrimitiveBezierSegmentMode { GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT_POSITION = 0, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT_OFFSET = 1, diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3600f36fa7a..dd31e85647d 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -172,12 +172,6 @@ typedef struct Object_Runtime { struct GeometrySet *geometry_set_eval; /** - * A GHash that contains geometry sets for intermediate stages of evaluation. The keys are just a - * hash and are not owned by the map. The geometry sets are owned. - */ - void *geometry_set_previews; - - /** * Mesh structure created during object evaluation. * It has deformation only modifiers applied on it. */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 0253de9f9d1..a51c532dfb3 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -74,8 +74,9 @@ typedef struct ParticleSpring { /* Child particles are created around or between parent particles */ typedef struct ChildParticle { - /** Num is face index on the final derived mesh. */ - int num, parent; + /** Face index on the final derived mesh. */ + int num; + int parent; /** Nearest particles to the child, used for the interpolation. */ int pa[4]; /** Interpolation weights for the above particles. */ diff --git a/source/blender/makesdna/DNA_pointcache_types.h b/source/blender/makesdna/DNA_pointcache_types.h index ad5f386bf2b..669c8500677 100644 --- a/source/blender/makesdna/DNA_pointcache_types.h +++ b/source/blender/makesdna/DNA_pointcache_types.h @@ -144,7 +144,7 @@ typedef struct PointCache { #define PTCACHE_FRAMES_SKIPPED (1 << 8) #define PTCACHE_EXTERNAL (1 << 9) #define PTCACHE_READ_INFO (1 << 10) -/** don't use the filename of the blendfile the data is linked from (write a local cache) */ +/** Don't use the filename of the blend-file the data is linked from (write a local cache). */ #define PTCACHE_IGNORE_LIBPATH (1 << 11) /** * High resolution cache is saved for smoke for backwards compatibility, diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5fc6cdf58a3..cd752b220a3 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2069,6 +2069,7 @@ enum { /** #SequencerToolSettings.snap_flag */ #define SEQ_SNAP_IGNORE_MUTED (1 << 0) #define SEQ_SNAP_IGNORE_SOUND (1 << 1) +#define SEQ_SNAP_CURRENT_FRAME_TO_STRIPS (1 << 2) /** #ToolSettings.snap_node_mode */ #define SCE_SNAP_MODE_NODE_X (1 << 0) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 557343f79cd..73a44ec16bb 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -727,6 +727,12 @@ typedef struct FileSelectParams { char renamefile[256]; short rename_flag; + char _pad[4]; + /** An ID that was just renamed. Used to identify a renamed asset file over re-reads, similar to + * `renamefile` but for local IDs (takes precedence). Don't keep this stored across handlers! + * Would break on undo. */ + const ID *rename_id; + void *_pad3; /** List of filetypes to filter (FILE_MAXFILE). */ char filter_glob[256]; @@ -734,7 +740,6 @@ typedef struct FileSelectParams { /** Text items name must match to be shown. */ char filter_search[64]; /** Same as filter, but for ID types (aka library groups). */ - int _pad0; uint64_t filter_id; /** Active file used for keyboard navigation. */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index fb1cf9b591d..f2a75a60a44 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -43,6 +43,7 @@ #define DNA_DEPRECATED_ALLOW +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -272,6 +273,37 @@ void print_struct_sizes(void); * Make DNA string (write to file). * \{ */ +static bool match_identifier_with_len(const char *str, + const char *identifier, + const size_t identifier_len) +{ + if (strncmp(str, identifier, identifier_len) == 0) { + /* Check `str` isn't a prefix to a longer identifier. */ + if (isdigit(str[identifier_len]) || isalpha(str[identifier_len]) || + (str[identifier_len] == '_')) { + return false; + } + return true; + } + return false; +} + +static bool match_identifier(const char *str, const char *identifier) +{ + const size_t identifier_len = strlen(identifier); + return match_identifier_with_len(str, identifier, identifier_len); +} + +static bool match_identifier_and_advance(char **str_ptr, const char *identifier) +{ + const size_t identifier_len = strlen(identifier); + if (match_identifier_with_len(*str_ptr, identifier, identifier_len)) { + (*str_ptr) += identifier_len; + return true; + } + return false; +} + static const char *version_struct_static_from_alias(const char *str) { const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_static_from_alias, str); @@ -619,7 +651,7 @@ static int preprocess_include(char *maindata, const int maindata_len) else if (cp[-1] == '*' && cp[0] == ' ') { /* pointers with a space */ } /* skip special keywords */ - else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) { + else if (match_identifier(cp, "DNA_DEPRECATED")) { /* single values are skipped already, so decrement 1 less */ a -= 13; cp += 13; @@ -721,7 +753,7 @@ static int convert_include(const char *filename) md1++; /* we've got a struct name when... */ - if (strncmp(md1 - 7, "struct", 6) == 0) { + if (match_identifier(md1 - 7, "struct")) { const int strct = add_type(md1, 0); if (strct == -1) { @@ -756,14 +788,22 @@ static int convert_include(const char *filename) /* skip when it says 'struct' or 'unsigned' or 'const' */ if (*md1) { - if (strncmp(md1, "struct", 6) == 0) { - md1 += 7; - } - if (strncmp(md1, "unsigned", 8) == 0) { - md1 += 9; - } - if (strncmp(md1, "const", 5) == 0) { - md1 += 6; + const char *md1_prev = md1; + while (match_identifier_and_advance(&md1, "struct") || + match_identifier_and_advance(&md1, "unsigned") || + match_identifier_and_advance(&md1, "const")) { + if (UNLIKELY(!ELEM(*md1, '\0', ' '))) { + /* This will happen with: `unsigned(*value)[3]` which isn't supported. */ + fprintf(stderr, + "File '%s' contains non white space character " + "\"%c\" after identifier \"%s\"\n", + filename, + *md1, + md1_prev); + return 1; + } + /* Skip ' ' or '\0'. */ + md1++; } /* we've got a type! */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 876229411e0..782d0924d21 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -450,6 +450,7 @@ extern StructRNA RNA_NodeOutputFileSlotFile; extern StructRNA RNA_NodeOutputFileSlotLayer; extern StructRNA RNA_NodeSocket; extern StructRNA RNA_NodeSocketInterface; +extern StructRNA RNA_NodeSocketStandard; extern StructRNA RNA_NodeTree; extern StructRNA RNA_NoiseGpencilModifier; extern StructRNA RNA_NoiseTexture; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 499b5538ad8..694636f0c94 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -772,7 +772,7 @@ static struct ID *rna_ID_make_local(struct ID *self, Main *bmain, bool clear_pro static AnimData *rna_ID_animation_data_create(ID *id, Main *bmain) { - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); DEG_relations_tag_update(bmain); return adt; } diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index 0dfd7d74c25..a9d5ef089bb 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -342,8 +342,8 @@ static void rna_def_canvas_surface(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; - /* Effect type - * Only used by ui to view per effect settings */ + /* Effect type + * Only used by UI to view per effect settings. */ static const EnumPropertyItem prop_dynamicpaint_effecttype[] = { {1, "SPREAD", 0, "Spread", ""}, {2, "DRIP", 0, "Drip", ""}, @@ -351,7 +351,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; - /* Displacemap file format */ + /* Displace-map file format. */ static const EnumPropertyItem prop_dynamicpaint_image_fileformat[] = { {MOD_DPAINT_IMGFORMAT_PNG, "PNG", 0, "PNG", ""}, # ifdef WITH_OPENEXR @@ -360,7 +360,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; - /* Displacemap type */ + /* Displace-map type. */ static const EnumPropertyItem prop_dynamicpaint_displace_type[] = { {MOD_DPAINT_DISP_DISPLACE, "DISPLACE", 0, "Displacement", ""}, {MOD_DPAINT_DISP_DEPTH, "DEPTH", 0, "Depth", ""}, diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 3fba8cdb035..9835d664a55 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -249,7 +249,7 @@ void RNA_api_mesh(StructRNA *srna) func = RNA_def_function(srna, "split_faces", "rna_Mesh_split_faces"); RNA_def_function_ui_description(func, "Split faces based on the edge angle"); RNA_def_boolean( - func, "free_loop_normals", 1, "Free Loop Notmals", "Free loop normals custom data layer"); + func, "free_loop_normals", 1, "Free Loop Normals", "Free loop normals custom data layer"); func = RNA_def_function(srna, "calc_tangents", "rna_Mesh_calc_tangents"); RNA_def_function_flag(func, FUNC_USE_REPORTS); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 2642ba82bc0..17c7b331c88 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -297,7 +297,7 @@ static int rna_NlaStrip_action_editable(PointerRNA *ptr, const char **UNUSED(r_i { NlaStrip *strip = (NlaStrip *)ptr->data; - /* strip actions shouldn't be editable if NLA tweakmode is on */ + /* Strip actions shouldn't be editable if NLA tweak-mode is on. */ if (ptr->owner_id) { AnimData *adt = BKE_animdata_from_id(ptr->owner_id); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 0a120837191..d576a5b7db6 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -799,7 +799,7 @@ const EnumPropertyItem *rna_node_socket_type_itemf(void *data, tmp.value = i; tmp.identifier = stype->idname; tmp.icon = RNA_struct_ui_icon(srna); - tmp.name = RNA_struct_ui_name(srna); + tmp.name = nodeSocketTypeLabel(stype); tmp.description = RNA_struct_ui_description(srna); RNA_enum_item_add(&item, &totitem, &tmp); @@ -1025,8 +1025,7 @@ static void rna_NodeTree_get_from_context( RNA_parameter_list_free(&list); } -static bool rna_NodeTree_valid_socket_type(eNodeSocketDatatype socket_type, - bNodeTreeType *ntreetype) +static bool rna_NodeTree_valid_socket_type(bNodeTreeType *ntreetype, bNodeSocketType *socket_type) { extern FunctionRNA rna_NodeTree_valid_socket_type_func; @@ -1040,7 +1039,7 @@ static bool rna_NodeTree_valid_socket_type(eNodeSocketDatatype socket_type, func = &rna_NodeTree_valid_socket_type_func; RNA_parameter_list_create(&list, &ptr, func); - RNA_parameter_set_lookup(&list, "type", &socket_type); + RNA_parameter_set_lookup(&list, "idname", &socket_type->idname); ntreetype->rna_ext.call(NULL, &ptr, func, &list); RNA_parameter_get_lookup(&list, "valid", &ret); @@ -2866,7 +2865,7 @@ static void rna_NodeSocket_type_set(PointerRNA *ptr, int value) bNodeSocket *sock = (bNodeSocket *)ptr->data; bNode *node; nodeFindNode(ntree, sock, &node, NULL); - nodeModifySocketType(ntree, node, sock, value, 0); + nodeModifySocketTypeStatic(ntree, node, sock, value, 0); } static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -3206,7 +3205,7 @@ static void rna_NodeSocketInterfaceStandard_draw(ID *id, struct uiLayout *layout) { PointerRNA ptr; - RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr); + RNA_pointer_create(id, &RNA_NodeSocketInterface, sock, &ptr); sock->typeinfo->interface_draw(C, layout, &ptr); } @@ -3216,7 +3215,7 @@ static void rna_NodeSocketInterfaceStandard_draw_color(ID *id, float r_color[4]) { PointerRNA ptr; - RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr); + RNA_pointer_create(id, &RNA_NodeSocketInterface, sock, &ptr); sock->typeinfo->interface_draw_color(C, &ptr, r_color); } @@ -9948,6 +9947,45 @@ static void def_geo_switch(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); } +static void def_geo_curve_primitive_quadrilateral(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem mode_items[] = { + {GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE, + "RECTANGLE", + 0, + "Rectangle", + "Create a rectangle"}, + {GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_PARALLELOGRAM, + "PARALLELOGRAM", + 0, + "Parallelogram", + "Create a parallelogram"}, + {GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_TRAPEZOID, + "TRAPEZOID", + 0, + "Trapezoid", + "Create a trapezoid"}, + {GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_KITE, "KITE", 0, "Kite", "Create a Kite / Dart"}, + {GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_POINTS, + "POINTS", + 0, + "Points", + "Create a quadrilateral from four points"}, + {0, NULL, 0, NULL, NULL}, + }; + + RNA_def_struct_sdna_from(srna, "NodeGeometryCurvePrimitiveQuad", "storage"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, mode_items); + RNA_def_property_enum_default(prop, GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE); + RNA_def_property_ui_text(prop, "Mode", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); +} + static void def_geo_curve_resample(StructRNA *srna) { PropertyRNA *prop; @@ -10176,7 +10214,7 @@ static void rna_def_node_socket(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Node Socket", "Input or output socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_refine_func(srna, "rna_NodeSocket_refine"); - RNA_def_struct_ui_icon(srna, ICON_PLUGIN); + RNA_def_struct_ui_icon(srna, ICON_NONE); RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); RNA_def_struct_register_funcs( srna, "rna_NodeSocket_register", "rna_NodeSocket_unregister", NULL); @@ -10281,6 +10319,11 @@ static void rna_def_node_socket(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", ""); + prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "typeinfo->label"); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + RNA_def_property_ui_text(prop, "Type Label", "Label to display for the socket type in the UI"); + /* draw socket */ func = RNA_def_function(srna, "draw", NULL); RNA_def_function_ui_description(func, "Draw socket"); @@ -10369,6 +10412,11 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", ""); + prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "typeinfo->label"); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + RNA_def_property_ui_text(prop, "Type Label", "Label to display for the socket type in the UI"); + func = RNA_def_function(srna, "draw", NULL); RNA_def_function_ui_description(func, "Draw template settings"); RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); @@ -11879,11 +11927,12 @@ static void rna_def_nodetree(BlenderRNA *brna) func, "result_3", "ID", "From ID", "Original ID data-block selected from the context"); RNA_def_function_output(func, parm); - /* Check for support of a socket type. */ + /* Check for support of a socket type with a type identifier. */ func = RNA_def_function(srna, "valid_socket_type", NULL); RNA_def_function_ui_description(func, "Check if the socket type is valid for the node tree"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL); - parm = RNA_def_enum(func, "type", node_socket_type_items, 0, "", ""); + parm = RNA_def_string( + func, "idname", "NodeSocket", MAX_NAME, "Socket Type", "Identifier of the socket type"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); RNA_def_function_return(func, RNA_def_boolean(func, "valid", false, "", "")); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 89c56de1077..0a91d5f01bc 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3535,6 +3535,11 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SEQ_SNAP_IGNORE_SOUND); RNA_def_property_ui_text(prop, "Ignore Sound Strips", "Don't snap to sound strips"); + prop = RNA_def_property(srna, "use_snap_current_frame_to_strips", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SEQ_SNAP_CURRENT_FRAME_TO_STRIPS); + RNA_def_property_ui_text( + prop, "Snap Current Frame to Strips", "Snap current frame to strip start or end"); + prop = RNA_def_property(srna, "snap_distance", PROP_INT, PROP_PIXEL); RNA_def_property_int_sdna(prop, NULL, "snap_distance"); RNA_def_property_int_default(prop, 15); @@ -7962,10 +7967,10 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "master_collection"); RNA_def_property_struct_type(prop, "Collection"); RNA_def_property_clear_flag(prop, PROP_PTR_NO_OWNERSHIP); - RNA_def_property_ui_text( - prop, - "Collection", - "Scene master collection that objects and other collections in the scene"); + RNA_def_property_ui_text(prop, + "Collection", + "Scene root collection that owns all the objects and other collections " + "instantiated in the scene"); /* Scene Display */ prop = RNA_def_property(srna, "display", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index caecd9a07d8..3e292ea89e2 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -207,7 +207,6 @@ static void rna_Scene_alembic_export(Scene *scene, bool apply_subdiv, bool flatten_hierarchy, bool visible_objects_only, - bool renderable_only, bool face_sets, bool use_subdiv_schema, bool export_hair, @@ -241,7 +240,6 @@ static void rna_Scene_alembic_export(Scene *scene, .apply_subdiv = apply_subdiv, .flatten_hierarchy = flatten_hierarchy, .visible_objects_only = visible_objects_only, - .renderable_only = renderable_only, .face_sets = face_sets, .use_subdiv_schema = use_subdiv_schema, .export_hair = export_hair, @@ -383,11 +381,6 @@ void RNA_api_scene(StructRNA *srna) 0, "Visible layers only", "Export only objects in visible layers"); - RNA_def_boolean(func, - "renderable_only", - 0, - "Renderable objects only", - "Export only objects marked renderable in the outliner"); RNA_def_boolean(func, "face_sets", 0, "Facesets", "Export face sets"); RNA_def_boolean(func, "subdiv_schema", diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index c5d8358272d..5f6456d3d1e 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -28,6 +28,7 @@ #include "DNA_sequence_types.h" #include "DNA_vfont_types.h" +#include "BLI_iterator.h" #include "BLI_math.h" #include "BLT_translation.h" @@ -102,17 +103,6 @@ typedef struct SequenceSearchData { SequenceModifierData *smd; } SequenceSearchData; -/* build a temp reference to the parent */ -static void meta_tmp_ref(Sequence *seq_par, Sequence *seq) -{ - for (; seq; seq = seq->next) { - seq->tmp = seq_par; - if (seq->type == SEQ_TYPE_META) { - meta_tmp_ref(seq, seq->seqbase.first); - } - } -} - static void rna_SequenceElement_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Scene *scene = (Scene *)ptr->owner_id; @@ -203,46 +193,41 @@ static void rna_SequenceEditor_sequences_all_begin(CollectionPropertyIterator *i { Scene *scene = (Scene *)ptr->owner_id; Editing *ed = SEQ_editing_get(scene, false); + SeqCollection *all_strips = SEQ_query_all_strips_recursive(&ed->seqbase); - meta_tmp_ref(NULL, ed->seqbase.first); + BLI_Iterator *bli_iter = MEM_callocN(sizeof(BLI_Iterator), __func__); + bli_iter->data = MEM_callocN(sizeof(SeqIterator), __func__); + iter->internal.custom = bli_iter; - rna_iterator_listbase_begin(iter, &ed->seqbase, NULL); -} - -static void rna_SequenceEditor_update_cache(Main *UNUSED(bmain), - Scene *scene, - PointerRNA *UNUSED(ptr)) -{ - Editing *ed = scene->ed; + if (!SEQ_iterator_ensure(all_strips, bli_iter->data, (Sequence **)&bli_iter->current)) { + SEQ_collection_free(all_strips); + } - SEQ_relations_free_imbuf(scene, &ed->seqbase, false); - SEQ_cache_cleanup(scene); + iter->valid = bli_iter->current != NULL; } static void rna_SequenceEditor_sequences_all_next(CollectionPropertyIterator *iter) { - ListBaseIterator *internal = &iter->internal.listbase; - Sequence *seq = (Sequence *)internal->link; + BLI_Iterator *bli_iter = iter->internal.custom; + bli_iter->current = SEQ_iterator_yield(bli_iter->data); + iter->valid = bli_iter->current != NULL; +} - if (seq->seqbase.first) { - internal->link = (Link *)seq->seqbase.first; - } - else if (seq->next) { - internal->link = (Link *)seq->next; - } - else { - internal->link = NULL; +static PointerRNA rna_SequenceEditor_sequences_all_get(CollectionPropertyIterator *iter) +{ + Sequence *seq = ((BLI_Iterator *)iter->internal.custom)->current; + return rna_pointer_inherit_refine(&iter->parent, &RNA_Sequence, seq); +} - do { - seq = seq->tmp; /* XXX: seq's don't reference their parents! */ - if (seq && seq->next) { - internal->link = (Link *)seq->next; - break; - } - } while (seq); +static void rna_SequenceEditor_sequences_all_end(CollectionPropertyIterator *iter) +{ + BLI_Iterator *bli_iter = iter->internal.custom; + SeqIterator *seq_iter = bli_iter->data; + if (seq_iter->collection != NULL) { + SEQ_collection_free(seq_iter->collection); } - - iter->valid = (internal->link != NULL); + MEM_freeN(seq_iter); + MEM_freeN(bli_iter); } static int rna_SequenceEditor_sequences_all_lookup_string(PointerRNA *ptr, @@ -260,6 +245,16 @@ static int rna_SequenceEditor_sequences_all_lookup_string(PointerRNA *ptr, return false; } +static void rna_SequenceEditor_update_cache(Main *UNUSED(bmain), + Scene *scene, + PointerRNA *UNUSED(ptr)) +{ + Editing *ed = scene->ed; + + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); + SEQ_cache_cleanup(scene); +} + /* internal use */ static int rna_SequenceEditor_elements_length(PointerRNA *ptr) { @@ -2009,8 +2004,8 @@ static void rna_def_editor(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, "rna_SequenceEditor_sequences_all_begin", "rna_SequenceEditor_sequences_all_next", - NULL, - NULL, + "rna_SequenceEditor_sequences_all_end", + "rna_SequenceEditor_sequences_all_get", NULL, NULL, "rna_SequenceEditor_sequences_all_lookup_string", diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c05842d3cfe..11110dd154a 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2106,7 +2106,7 @@ static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr) switch (saction->mode) { case SACTCONT_ACTION: /* TODO: context selector could help decide this with more control? */ - adt = BKE_animdata_add_id(&obact->id); + adt = BKE_animdata_ensure_id(&obact->id); id = &obact->id; break; case SACTCONT_SHAPEKEY: { @@ -2114,7 +2114,7 @@ static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr) if (key == NULL) { return; } - adt = BKE_animdata_add_id(&key->id); + adt = BKE_animdata_ensure_id(&key->id); id = &key->id; break; } @@ -2136,7 +2136,7 @@ static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr) return; } - /* Exit editmode first - we cannot change actions while in tweakmode. */ + /* Exit editmode first - we cannot change actions while in tweak-mode. */ BKE_nla_tweakmode_exit(adt); /* To prevent data loss (i.e. if users flip between actions using the Browse menu), diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner.py b/source/blender/makesrna/rna_cleanup/rna_cleaner.py index 61622f281a6..f5e5e32ee76 100755 --- a/source/blender/makesrna/rna_cleanup/rna_cleaner.py +++ b/source/blender/makesrna/rna_cleanup/rna_cleaner.py @@ -229,7 +229,7 @@ def sort(props_list, sort_priority): def file_basename(input_filename): - # if needed will use os.path + # If needed will use `os.path`. if input_filename.endswith(".txt"): if input_filename.endswith("_work.txt"): base_filename = input_filename.replace("_work.txt", "") diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 4b9b24e4e47..bdb791dc8e7 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -109,7 +109,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u { BooleanModifierData *bmd = (BooleanModifierData *)md; - walk(userData, ob, (ID **)&bmd->collection, IDWALK_CB_NOP); + walk(userData, ob, (ID **)&bmd->collection, IDWALK_CB_USER); walk(userData, ob, (ID **)&bmd->object, IDWALK_CB_NOP); } diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index c38e5126f6b..52f21e3d3d0 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -101,7 +101,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct range_vn_i(faceMap, numPoly_src, 0); struct Scene *scene = DEG_get_input_scene(ctx->depsgraph); - frac = (BKE_scene_frame_get(scene) - bmd->start) / bmd->length; + frac = (BKE_scene_ctime_get(scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); if (bmd->flag & MOD_BUILD_FLAG_REVERSE) { frac = 1.0f - frac; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 545e23221ec..bf197dca7e5 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -919,7 +919,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, EdgeHashIterator *ehi; float *vertco = NULL, imat[4][4]; float rot[4]; - float cfra; + float ctime; /* float timestep; */ const int *facepa = emd->facepa; int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0; @@ -940,7 +940,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* timestep = psys_get_timestep(&sim); */ - cfra = BKE_scene_frame_get(scene); + ctime = BKE_scene_ctime_get(scene); /* hash table for vertice <-> particle relations */ vertpahash = BLI_edgehash_new(__func__); @@ -962,7 +962,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* do mindex + totvert to ensure the vertex index to be the first * with BLI_edgehashIterator_getKey */ - if (pa == NULL || cfra < pa->time) { + if (pa == NULL || ctime < pa->time) { mindex = totvert + totpart; } else { @@ -1022,7 +1022,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, psys_get_birth_coords(&sim, pa, &birth, 0, 0); - state.time = cfra; + state.time = ctime; psys_get_particle_state(&sim, ed_v2, &state, 1); vertco = explode->mvert[v].co; @@ -1076,7 +1076,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, orig_v4 = source.v4; /* Same as above in the first loop over mesh's faces. */ - if (pa == NULL || cfra < pa->time) { + if (pa == NULL || ctime < pa->time) { mindex = totvert + totpart; } else { @@ -1096,7 +1096,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* override uv channel for particle age */ if (mtface) { - float age = (pa != NULL) ? (cfra - pa->time) / pa->lifetime : 0.0f; + float age = (pa != NULL) ? (ctime - pa->time) / pa->lifetime : 0.0f; /* Clamp to this range to avoid flipping to the other side of the coordinates. */ CLAMP(age, 0.001f, 0.999f); diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 6ec3277ee7a..e0507320628 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -104,20 +104,20 @@ static void meshcache_do(MeshCacheModifierData *mcmd, /* -------------------------------------------------------------------- */ /* Interpret Time (the reading functions also do some of this ) */ if (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA) { - const float cfra = BKE_scene_frame_get(scene); + const float ctime = BKE_scene_ctime_get(scene); switch (mcmd->time_mode) { case MOD_MESHCACHE_TIME_FRAME: { - time = cfra; + time = ctime; break; } case MOD_MESHCACHE_TIME_SECONDS: { - time = cfra / fps; + time = ctime / fps; break; } case MOD_MESHCACHE_TIME_FACTOR: default: { - time = cfra / fps; + time = ctime / fps; break; } } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index bee74bcbf73..87fce26c45e 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -48,6 +48,7 @@ #include "DNA_space_types.h" #include "DNA_windowmanager_types.h" +#include "BKE_attribute_math.hh" #include "BKE_customdata.h" #include "BKE_geometry_set_instances.hh" #include "BKE_global.h" @@ -56,7 +57,6 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_modifier.h" -#include "BKE_node_ui_storage.hh" #include "BKE_object.h" #include "BKE_pointcloud.h" #include "BKE_screen.h" @@ -83,8 +83,10 @@ #include "NOD_derived_node_tree.hh" #include "NOD_geometry.h" +#include "NOD_geometry_nodes_eval_log.hh" #include "NOD_node_tree_multi_function.hh" +using blender::destruct_ptr; using blender::float3; using blender::FunctionRef; using blender::IndexRange; @@ -97,6 +99,7 @@ using blender::Vector; using blender::fn::GMutablePointer; using blender::fn::GPointer; using blender::nodes::GeoNodeExecParams; +using blender::threading::EnumerableThreadSpecific; using namespace blender::fn::multi_function_types; using namespace blender::nodes::derived_node_tree_types; @@ -734,19 +737,6 @@ static void initialize_group_input(NodesModifierData &nmd, property_type->init_cpp_value(*property, r_value); } -static void reset_tree_ui_storage(Span<const blender::nodes::NodeTreeRef *> trees, - const Object &object, - const ModifierData &modifier) -{ - const NodeTreeEvaluationContext context = {object, modifier}; - - for (const blender::nodes::NodeTreeRef *tree : trees) { - bNodeTree *btree_cow = tree->btree(); - bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow); - BKE_nodetree_ui_storage_free_for_context(*btree_original, context); - } -} - static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain) { wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; @@ -766,8 +756,6 @@ static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain) return spreadsheets; } -using PreviewSocketMap = blender::MultiValueMap<DSocket, uint64_t>; - static DSocket try_get_socket_to_preview_for_spreadsheet(SpaceSpreadsheet *sspreadsheet, NodesModifierData *nmd, const ModifierEvalContext *ctx, @@ -821,19 +809,10 @@ static DSocket try_get_socket_to_preview_for_spreadsheet(SpaceSpreadsheet *sspre } const NodeTreeRef &tree_ref = context->tree(); - for (const NodeRef *node_ref : tree_ref.nodes()) { + for (const NodeRef *node_ref : tree_ref.nodes_by_type("GeometryNodeViewer")) { if (node_ref->name() == last_context->node_name) { const DNode viewer_node{context, node_ref}; - DSocket socket_to_view; - viewer_node.input(0).foreach_origin_socket( - [&](const DSocket socket) { socket_to_view = socket; }); - if (!socket_to_view) { - return {}; - } - bNodeSocket *bsocket = socket_to_view->bsocket(); - if (bsocket->type == SOCK_GEOMETRY && bsocket->flag != SOCK_MULTI_INPUT) { - return socket_to_view; - } + return viewer_node.input(0); } } return {}; @@ -842,7 +821,7 @@ static DSocket try_get_socket_to_preview_for_spreadsheet(SpaceSpreadsheet *sspre static void find_sockets_to_preview(NodesModifierData *nmd, const ModifierEvalContext *ctx, const DerivedNodeTree &tree, - PreviewSocketMap &r_sockets_to_preview) + Set<DSocket> &r_sockets_to_preview) { Main *bmain = DEG_get_bmain(ctx->depsgraph); @@ -852,51 +831,16 @@ static void find_sockets_to_preview(NodesModifierData *nmd, for (SpaceSpreadsheet *sspreadsheet : spreadsheets) { const DSocket socket = try_get_socket_to_preview_for_spreadsheet(sspreadsheet, nmd, ctx, tree); if (socket) { - const uint64_t key = ED_spreadsheet_context_path_hash(sspreadsheet); - r_sockets_to_preview.add_non_duplicates(socket, key); + r_sockets_to_preview.add(socket); } } } -static void log_preview_socket_value(const Span<GPointer> values, - Object *object, - Span<uint64_t> keys) +static void clear_runtime_data(NodesModifierData *nmd) { - GeometrySet geometry_set = *(const GeometrySet *)values[0].get(); - geometry_set.ensure_owns_direct_data(); - for (uint64_t key : keys) { - BKE_object_preview_geometry_set_add(object, key, new GeometrySet(geometry_set)); - } -} - -static void log_ui_hints(const DSocket socket, - const Span<GPointer> values, - Object *self_object, - NodesModifierData *nmd) -{ - const DNode node = socket.node(); - if (node->is_reroute_node() || socket->typeinfo()->type != SOCK_GEOMETRY) { - return; - } - bNodeTree *btree_cow = node->btree(); - bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow); - const NodeTreeEvaluationContext context{*self_object, nmd->modifier}; - for (const GPointer &data : values) { - if (data.type() == &CPPType::get<GeometrySet>()) { - const GeometrySet &geometry_set = *(const GeometrySet *)data.get(); - blender::bke::geometry_set_instances_attribute_foreach( - geometry_set, - [&](StringRefNull attribute_name, const AttributeMetaData &meta_data) { - BKE_nodetree_attribute_hint_add(*btree_original, - context, - *node->bnode(), - attribute_name, - meta_data.domain, - meta_data.data_type); - return true; - }, - 8); - } + if (nmd->runtime_eval_log != nullptr) { + delete (geo_log::ModifierLog *)nmd->runtime_eval_log; + nmd->runtime_eval_log = nullptr; } } @@ -952,32 +896,32 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree, Vector<DInputSocket> group_outputs; group_outputs.append({root_context, &socket_to_compute}); - PreviewSocketMap preview_sockets; - find_sockets_to_preview(nmd, ctx, tree, preview_sockets); - - auto log_socket_value = [&](const DSocket socket, const Span<GPointer> values) { - if (!logging_enabled(ctx)) { - return; - } - Span<uint64_t> keys = preview_sockets.lookup(socket); - if (!keys.is_empty()) { - log_preview_socket_value(values, ctx->object, keys); - } - log_ui_hints(socket, values, ctx->object, nmd); - }; + std::optional<geo_log::GeoLogger> geo_logger; blender::modifiers::geometry_nodes::GeometryNodesEvaluationParams eval_params; + + if (logging_enabled(ctx)) { + Set<DSocket> preview_sockets; + find_sockets_to_preview(nmd, ctx, tree, preview_sockets); + eval_params.force_compute_sockets.extend(preview_sockets.begin(), preview_sockets.end()); + geo_logger.emplace(std::move(preview_sockets)); + } + eval_params.input_values = group_inputs; eval_params.output_sockets = group_outputs; - eval_params.force_compute_sockets.extend(preview_sockets.keys().begin(), - preview_sockets.keys().end()); eval_params.mf_by_node = &mf_by_node; eval_params.modifier_ = nmd; eval_params.depsgraph = ctx->depsgraph; eval_params.self_object = ctx->object; - eval_params.log_socket_value_fn = log_socket_value; + eval_params.geo_logger = geo_logger.has_value() ? &*geo_logger : nullptr; blender::modifiers::geometry_nodes::evaluate_geometry_nodes(eval_params); + if (geo_logger.has_value()) { + NodesModifierData *nmd_orig = (NodesModifierData *)BKE_modifier_get_original(&nmd->modifier); + clear_runtime_data(nmd_orig); + nmd_orig->runtime_eval_log = new geo_log::ModifierLog(*geo_logger); + } + BLI_assert(eval_params.r_output_values.size() == 1); GMutablePointer result = eval_params.r_output_values[0]; return result.relocate_out<GeometrySet>(); @@ -1067,10 +1011,6 @@ static void modifyGeometry(ModifierData *md, return; } - if (logging_enabled(ctx)) { - reset_tree_ui_storage(tree.used_node_tree_refs(), *ctx->object, *md); - } - geometry_set = compute_geometry( tree, input_nodes, *group_outputs[0], std::move(geometry_set), nmd, ctx); } @@ -1081,9 +1021,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * modifyGeometry(md, ctx, geometry_set); - /* This function is only called when applying modifiers. In this case it makes sense to realize - * instances, otherwise in some cases there might be no results when applying the modifier. */ - geometry_set = blender::bke::geometry_set_realize_mesh_for_modifier(geometry_set); + if (ctx->flag & MOD_APPLY_TO_BASE_MESH) { + /* In this case it makes sense to realize instances, otherwise in some cases there might be no + * results when applying the modifier. */ + geometry_set = blender::bke::geometry_set_realize_mesh_for_modifier(geometry_set); + } Mesh *new_mesh = geometry_set.get_component_for_write<MeshComponent>().release(); if (new_mesh == nullptr) { @@ -1214,6 +1156,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md); BLO_read_data_address(reader, &nmd->settings.properties); IDP_BlendDataRead(reader, &nmd->settings.properties); + nmd->runtime_eval_log = nullptr; } static void copyData(const ModifierData *md, ModifierData *target, const int flag) @@ -1223,6 +1166,8 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla BKE_modifier_copydata_generic(md, target, flag); + tnmd->runtime_eval_log = nullptr; + if (nmd->settings.properties != nullptr) { tnmd->settings.properties = IDP_CopyProperty_ex(nmd->settings.properties, flag); } @@ -1235,6 +1180,8 @@ static void freeData(ModifierData *md) IDP_FreeProperty_ex(nmd->settings.properties, false); nmd->settings.properties = nullptr; } + + clear_runtime_data(nmd); } static void requiredDataMask(Object *UNUSED(ob), diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc index 205bfa34465..18cc1ce6c86 100644 --- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc +++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc @@ -558,11 +558,11 @@ class GeometryNodesEvaluator { for (auto &&item : params_.input_values.items()) { const DOutputSocket socket = item.key; GMutablePointer value = item.value; - this->log_socket_value(socket, value); const DNode node = socket.node(); if (!node_states_.contains_as(node)) { /* The socket is not connected to any output. */ + this->log_socket_value({socket}, value); value.destruct(); continue; } @@ -780,7 +780,6 @@ class GeometryNodesEvaluator { /* Checks if all the linked sockets have been provided already. */ if (multi_value.items.size() == multi_value.expected_size) { input_state.was_ready_for_execution = true; - this->log_socket_value(socket, input_state, multi_value.items); } else if (is_required) { /* The input is required but is not fully provided yet. Therefore the node cannot be @@ -792,7 +791,6 @@ class GeometryNodesEvaluator { SingleInputValue &single_value = *input_state.value.single; if (single_value.value != nullptr) { input_state.was_ready_for_execution = true; - this->log_socket_value(socket, GPointer{input_state.type, single_value.value}); } else if (is_required) { /* The input is required but has not been provided yet. Therefore the node cannot be @@ -1170,6 +1168,9 @@ class GeometryNodesEvaluator { { BLI_assert(value_to_forward.get() != nullptr); + Vector<DSocket> sockets_to_log_to; + sockets_to_log_to.append(from_socket); + Vector<DInputSocket> to_sockets; auto handle_target_socket_fn = [&, this](const DInputSocket to_socket) { if (this->should_forward_to_socket(to_socket)) { @@ -1177,9 +1178,7 @@ class GeometryNodesEvaluator { } }; auto handle_skipped_socket_fn = [&, this](const DSocket socket) { - /* Log socket value on intermediate sockets to support e.g. attribute search or spreadsheet - * breadcrumbs on group nodes. */ - this->log_socket_value(socket, value_to_forward); + sockets_to_log_to.append(socket); }; from_socket.foreach_target_socket(handle_target_socket_fn, handle_skipped_socket_fn); @@ -1192,11 +1191,18 @@ class GeometryNodesEvaluator { if (from_type == to_type) { /* All target sockets that do not need a conversion will be handled afterwards. */ to_sockets_same_type.append(to_socket); + /* Multi input socket values are logged once all values are available. */ + if (!to_socket->is_multi_input_socket()) { + sockets_to_log_to.append(to_socket); + } continue; } this->forward_to_socket_with_different_type( allocator, value_to_forward, from_socket, to_socket, to_type); } + + this->log_socket_value(sockets_to_log_to, value_to_forward); + this->forward_to_sockets_with_same_type( allocator, to_sockets_same_type, value_to_forward, from_socket); } @@ -1227,6 +1233,7 @@ class GeometryNodesEvaluator { /* Allocate a buffer for the converted value. */ void *buffer = allocator.allocate(to_type.size(), to_type.alignment()); + GMutablePointer value{to_type, buffer}; if (conversions_.is_convertible(from_type, to_type)) { /* Do the conversion if possible. */ @@ -1236,7 +1243,11 @@ class GeometryNodesEvaluator { /* Cannot convert, use default value instead. */ to_type.copy_construct(to_type.default_value(), buffer); } - this->add_value_to_input_socket(to_socket, from_socket, {to_type, buffer}); + /* Multi input socket values are logged once all values are available. */ + if (!to_socket->is_multi_input_socket()) { + this->log_socket_value({to_socket}, value); + } + this->add_value_to_input_socket(to_socket, from_socket, value); } void forward_to_sockets_with_same_type(LinearAllocator<> &allocator, @@ -1284,6 +1295,10 @@ class GeometryNodesEvaluator { /* Add a new value to the multi-input. */ MultiInputValue &multi_value = *input_state.value.multi; multi_value.items.append({origin, value.get()}); + + if (multi_value.expected_size == multi_value.items.size()) { + this->log_socket_value({socket}, input_state, multi_value.items); + } } else { /* Assign the value to the input. */ @@ -1314,10 +1329,14 @@ class GeometryNodesEvaluator { if (input_socket->is_multi_input_socket()) { MultiInputValue &multi_value = *input_state.value.multi; multi_value.items.append({origin_socket, value.get()}); + if (multi_value.expected_size == multi_value.items.size()) { + this->log_socket_value({input_socket}, input_state, multi_value.items); + } } else { SingleInputValue &single_value = *input_state.value.single; single_value.value = value.get(); + this->log_socket_value({input_socket}, value); } } @@ -1370,29 +1389,27 @@ class GeometryNodesEvaluator { return *node_states_.lookup_key_as(node).state; } - void log_socket_value(const DSocket socket, Span<GPointer> values) + void log_socket_value(DSocket socket, InputState &input_state, Span<MultiInputValueItem> values) { - if (params_.log_socket_value_fn) { - params_.log_socket_value_fn(socket, values); + if (params_.geo_logger == nullptr) { + return; } - } - void log_socket_value(const DSocket socket, - InputState &input_state, - Span<MultiInputValueItem> values) - { Vector<GPointer, 16> value_pointers; value_pointers.reserve(values.size()); const CPPType &type = *input_state.type; for (const MultiInputValueItem &item : values) { value_pointers.append({type, item.value}); } - this->log_socket_value(socket, value_pointers); + params_.geo_logger->local().log_multi_value_socket(socket, value_pointers); } - void log_socket_value(const DSocket socket, GPointer value) + void log_socket_value(Span<DSocket> sockets, GPointer value) { - this->log_socket_value(socket, Span<GPointer>(&value, 1)); + if (params_.geo_logger == nullptr) { + return; + } + params_.geo_logger->local().log_value_for_sockets(sockets, value); } /* In most cases when `NodeState` is accessed, the node has to be locked first to avoid race @@ -1431,6 +1448,7 @@ NodeParamsProvider::NodeParamsProvider(GeometryNodesEvaluator &evaluator, this->self_object = evaluator.params_.self_object; this->modifier = &evaluator.params_.modifier_->modifier; this->depsgraph = evaluator.params_.depsgraph; + this->logger = evaluator.params_.geo_logger; } bool NodeParamsProvider::can_get_input(StringRef identifier) const @@ -1530,8 +1548,6 @@ void NodeParamsProvider::set_output(StringRef identifier, GMutablePointer value) const DOutputSocket socket = this->dnode.output_by_identifier(identifier); BLI_assert(socket); - evaluator_.log_socket_value(socket, value); - OutputState &output_state = node_state_.outputs[socket->index()]; BLI_assert(!output_state.has_been_computed); evaluator_.forward_output(socket, value); diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.hh b/source/blender/modifiers/intern/MOD_nodes_evaluator.hh index 58eb6a4cd0b..f4ee6242dcb 100644 --- a/source/blender/modifiers/intern/MOD_nodes_evaluator.hh +++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.hh @@ -19,20 +19,21 @@ #include "BLI_map.hh" #include "NOD_derived_node_tree.hh" +#include "NOD_geometry_nodes_eval_log.hh" #include "NOD_node_tree_multi_function.hh" #include "FN_generic_pointer.hh" #include "DNA_modifier_types.h" +namespace geo_log = blender::nodes::geometry_nodes_eval_log; + namespace blender::modifiers::geometry_nodes { using namespace nodes::derived_node_tree_types; using fn::GMutablePointer; using fn::GPointer; -using LogSocketValueFn = std::function<void(DSocket, Span<GPointer>)>; - struct GeometryNodesEvaluationParams { blender::LinearAllocator<> allocator; @@ -48,7 +49,7 @@ struct GeometryNodesEvaluationParams { const NodesModifierData *modifier_; Depsgraph *depsgraph; Object *self_object; - LogSocketValueFn log_socket_value_fn; + geo_log::GeoLogger *geo_logger; Vector<GMutablePointer> r_output_values; }; diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 38cce5e6a50..ef70f3fe6f4 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -120,7 +120,6 @@ static void deformVerts(ModifierData *md, Mesh *mesh_src = mesh; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; ParticleSystem *psys = NULL; - /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ctx->object->particlesystem.first) { psys = psmd->psys; diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 5df67830baf..e97190b1878 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -1027,14 +1027,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_rim) { uint i; - /* bugger, need to re-calculate the normals for the new edge faces. + /* NOTE(campbell): Unfortunately re-calculate the normals for the new edge faces is necessary. * This could be done in many ways, but probably the quickest way * is to calculate the average normals for side faces only. * Then blend them with the normals of the edge verts. * - * at the moment its easiest to allocate an entire array for every vertex, - * even though we only need edge verts - campbell - */ + * At the moment its easiest to allocate an entire array for every vertex, + * even though we only need edge verts. */ #define SOLIDIFY_SIDE_NORMALS diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 74ba85426c6..dc19508be04 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -164,18 +164,20 @@ set(SRC geometry/nodes/node_geo_collection_info.cc geometry/nodes/node_geo_common.cc geometry/nodes/node_geo_convex_hull.cc - geometry/nodes/node_geo_curve_length.cc + geometry/nodes/node_geo_curve_endpoints.cc + geometry/nodes/node_geo_curve_length.cc geometry/nodes/node_geo_curve_primitive_bezier_segment.cc geometry/nodes/node_geo_curve_primitive_circle.cc geometry/nodes/node_geo_curve_primitive_line.cc geometry/nodes/node_geo_curve_primitive_quadratic_bezier.cc + geometry/nodes/node_geo_curve_primitive_quadrilateral.cc geometry/nodes/node_geo_curve_primitive_spiral.cc geometry/nodes/node_geo_curve_primitive_star.cc - geometry/nodes/node_geo_curve_to_mesh.cc - geometry/nodes/node_geo_curve_to_points.cc geometry/nodes/node_geo_curve_resample.cc geometry/nodes/node_geo_curve_reverse.cc geometry/nodes/node_geo_curve_subdivide.cc + geometry/nodes/node_geo_curve_to_mesh.cc + geometry/nodes/node_geo_curve_to_points.cc geometry/nodes/node_geo_delete_geometry.cc geometry/nodes/node_geo_edge_split.cc geometry/nodes/node_geo_input_material.cc @@ -191,6 +193,7 @@ set(SRC geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc geometry/nodes/node_geo_mesh_primitive_line.cc geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc + geometry/nodes/node_geo_mesh_subdivide.cc geometry/nodes/node_geo_mesh_to_curve.cc geometry/nodes/node_geo_object_info.cc geometry/nodes/node_geo_point_distribute.cc @@ -203,7 +206,6 @@ set(SRC geometry/nodes/node_geo_raycast.cc geometry/nodes/node_geo_select_by_material.cc geometry/nodes/node_geo_separate_components.cc - geometry/nodes/node_geo_subdivide.cc geometry/nodes/node_geo_subdivision_surface.cc geometry/nodes/node_geo_switch.cc geometry/nodes/node_geo_transform.cc @@ -334,6 +336,7 @@ set(SRC texture/node_texture_util.c intern/derived_node_tree.cc + intern/geometry_nodes_eval_log.cc intern/math_functions.cc intern/node_common.c intern/node_exec.cc @@ -357,6 +360,7 @@ set(SRC NOD_function.h NOD_geometry.h NOD_geometry_exec.hh + NOD_geometry_nodes_eval_log.hh NOD_math_functions.hh NOD_node_tree_multi_function.hh NOD_node_tree_ref.hh @@ -417,6 +421,11 @@ if(WITH_TBB) ${TBB_INCLUDE_DIRS} ) add_definitions(-DWITH_TBB) + if(WIN32) + # TBB includes Windows.h which will define min/max macros + # that will collide with the stl versions. + add_definitions(-DNOMINMAX) + endif() endif() if(WITH_IMAGE_OPENEXR) diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index 99f95e7f07e..ad3a838f4c0 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -42,27 +42,29 @@ void register_node_type_geo_attribute_math(void); void register_node_type_geo_attribute_mix(void); void register_node_type_geo_attribute_proximity(void); void register_node_type_geo_attribute_randomize(void); +void register_node_type_geo_attribute_remove(void); void register_node_type_geo_attribute_separate_xyz(void); void register_node_type_geo_attribute_transfer(void); void register_node_type_geo_attribute_vector_math(void); void register_node_type_geo_attribute_vector_rotate(void); -void register_node_type_geo_attribute_remove(void); void register_node_type_geo_boolean(void); void register_node_type_geo_bounding_box(void); void register_node_type_geo_collection_info(void); void register_node_type_geo_convex_hull(void); +void register_node_type_geo_curve_endpoints(void); void register_node_type_geo_curve_length(void); void register_node_type_geo_curve_primitive_bezier_segment(void); void register_node_type_geo_curve_primitive_circle(void); void register_node_type_geo_curve_primitive_line(void); void register_node_type_geo_curve_primitive_quadratic_bezier(void); +void register_node_type_geo_curve_primitive_quadrilateral(void); void register_node_type_geo_curve_primitive_spiral(void); void register_node_type_geo_curve_primitive_star(void); -void register_node_type_geo_curve_to_mesh(void); -void register_node_type_geo_curve_to_points(void); void register_node_type_geo_curve_resample(void); void register_node_type_geo_curve_reverse(void); void register_node_type_geo_curve_subdivide(void); +void register_node_type_geo_curve_to_mesh(void); +void register_node_type_geo_curve_to_points(void); void register_node_type_geo_delete_geometry(void); void register_node_type_geo_edge_split(void); void register_node_type_geo_input_material(void); @@ -78,6 +80,7 @@ void register_node_type_geo_mesh_primitive_grid(void); void register_node_type_geo_mesh_primitive_ico_sphere(void); void register_node_type_geo_mesh_primitive_line(void); void register_node_type_geo_mesh_primitive_uv_sphere(void); +void register_node_type_geo_mesh_subdivide(void); void register_node_type_geo_mesh_to_curve(void); void register_node_type_geo_object_info(void); void register_node_type_geo_point_distribute(void); @@ -91,7 +94,6 @@ void register_node_type_geo_raycast(void); void register_node_type_geo_sample_texture(void); void register_node_type_geo_select_by_material(void); void register_node_type_geo_separate_components(void); -void register_node_type_geo_subdivide(void); void register_node_type_geo_subdivision_surface(void); void register_node_type_geo_switch(void); void register_node_type_geo_transform(void); diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 23474201daa..d6a23051c0b 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -21,11 +21,11 @@ #include "BKE_attribute_access.hh" #include "BKE_geometry_set.hh" #include "BKE_geometry_set_instances.hh" -#include "BKE_node_ui_storage.hh" #include "DNA_node_types.h" #include "NOD_derived_node_tree.hh" +#include "NOD_geometry_nodes_eval_log.hh" struct Depsgraph; struct ModifierData; @@ -52,10 +52,11 @@ using fn::GVMutableArray; using fn::GVMutableArray_GSpan; using fn::GVMutableArray_Typed; using fn::GVMutableArrayPtr; +using geometry_nodes_eval_log::NodeWarningType; /** - * This class exists to separate the memory management details of the geometry nodes evaluator from - * the node execution functions and related utilities. + * This class exists to separate the memory management details of the geometry nodes evaluator + * from the node execution functions and related utilities. */ class GeoNodeExecParamsProvider { public: @@ -63,6 +64,7 @@ class GeoNodeExecParamsProvider { const Object *self_object = nullptr; const ModifierData *modifier = nullptr; Depsgraph *depsgraph = nullptr; + geometry_nodes_eval_log::GeoLogger *logger = nullptr; /** * Returns true when the node is allowed to get/extract the input value. The identifier is diff --git a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh new file mode 100644 index 00000000000..1c4590f96ac --- /dev/null +++ b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh @@ -0,0 +1,291 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +/** + * Many geometry nodes related UI features need access to data produced during evaluation. Not only + * is the final output required but also the intermediate results. Those features include + * attribute search, node warnings, socket inspection and the viewer node. + * + * This file provides the framework for logging data during evaluation and accessing the data after + * evaluation. + * + * During logging every thread gets its own local logger to avoid too much locking (logging + * generally happens for every socket). After geometry nodes evaluation is done, the thread-local + * logging information is combined and post-processed to make it easier for the UI to lookup. + * necessary information. + */ + +#include "BLI_enumerable_thread_specific.hh" +#include "BLI_linear_allocator.hh" +#include "BLI_map.hh" + +#include "BKE_geometry_set.hh" + +#include "FN_generic_pointer.hh" + +#include "NOD_derived_node_tree.hh" + +struct SpaceNode; +struct SpaceSpreadsheet; + +namespace blender::nodes::geometry_nodes_eval_log { + +using fn::GMutablePointer; +using fn::GPointer; + +/** Contains information about a value that has been computed during geometry nodes evaluation. */ +class ValueLog { + public: + virtual ~ValueLog() = default; +}; + +/** Contains an owned copy of a value of a generic type. */ +class GenericValueLog : public ValueLog { + private: + GMutablePointer data_; + + public: + GenericValueLog(GMutablePointer data) : data_(data) + { + } + + ~GenericValueLog() + { + data_.destruct(); + } + + GPointer value() const + { + return data_; + } +}; + +struct GeometryAttributeInfo { + std::string name; + AttributeDomain domain; + CustomDataType data_type; +}; + +/** Contains information about a geometry set. In most cases this does not store the entire + * geometry set as this would require too much memory. */ +class GeometryValueLog : public ValueLog { + private: + Vector<GeometryAttributeInfo> attributes_; + Vector<GeometryComponentType> component_types_; + std::unique_ptr<GeometrySet> full_geometry_; + + public: + GeometryValueLog(const GeometrySet &geometry_set, bool log_full_geometry); + + Span<GeometryAttributeInfo> attributes() const + { + return attributes_; + } + + Span<GeometryComponentType> component_types() const + { + return component_types_; + } + + const GeometrySet *full_geometry() const + { + return full_geometry_.get(); + } +}; + +enum class NodeWarningType { + Error, + Warning, + Info, +}; + +struct NodeWarning { + NodeWarningType type; + std::string message; +}; + +struct NodeWithWarning { + DNode node; + NodeWarning warning; +}; + +/** The same value can be referenced by multiple sockets when they are linked. */ +struct ValueOfSockets { + Span<DSocket> sockets; + destruct_ptr<ValueLog> value; +}; + +class GeoLogger; +class ModifierLog; + +/** Every thread has its own local logger to avoid having to communicate between threads during + * evaluation. After evaluation the individual logs are combined. */ +class LocalGeoLogger { + private: + /* Back pointer to the owner of this local logger. */ + GeoLogger *main_logger_; + /* Allocator for the many small allocations during logging. This is in a `unique_ptr` so that + * ownership can be transferred later on. */ + std::unique_ptr<LinearAllocator<>> allocator_; + Vector<ValueOfSockets> values_; + Vector<NodeWithWarning> node_warnings_; + + friend ModifierLog; + + public: + LocalGeoLogger(GeoLogger &main_logger) : main_logger_(&main_logger) + { + this->allocator_ = std::make_unique<LinearAllocator<>>(); + } + + void log_value_for_sockets(Span<DSocket> sockets, GPointer value); + void log_multi_value_socket(DSocket socket, Span<GPointer> values); + void log_node_warning(DNode node, NodeWarningType type, std::string message); +}; + +/** The root logger class. */ +class GeoLogger { + private: + /** The entire geometry of sockets in this set should be cached, because e.g. the spreadsheet + * displays the data. We don't log the entire geometry at all places, because that would require + * way too much memory. */ + Set<DSocket> log_full_geometry_sockets_; + threading::EnumerableThreadSpecific<LocalGeoLogger> threadlocals_; + + friend LocalGeoLogger; + + public: + GeoLogger(Set<DSocket> log_full_geometry_sockets) + : log_full_geometry_sockets_(std::move(log_full_geometry_sockets)), + threadlocals_([this]() { return LocalGeoLogger(*this); }) + { + } + + LocalGeoLogger &local() + { + return threadlocals_.local(); + } + + auto begin() + { + return threadlocals_.begin(); + } + + auto end() + { + return threadlocals_.end(); + } +}; + +/** Contains information that has been logged for one specific socket. */ +class SocketLog { + private: + ValueLog *value_ = nullptr; + + friend ModifierLog; + + public: + const ValueLog *value() const + { + return value_; + } +}; + +/** Contains information that has been logged for one specific node. */ +class NodeLog { + private: + Vector<SocketLog> input_logs_; + Vector<SocketLog> output_logs_; + Vector<NodeWarning, 0> warnings_; + + friend ModifierLog; + + public: + const SocketLog *lookup_socket_log(eNodeSocketInOut in_out, int index) const; + const SocketLog *lookup_socket_log(const bNode &node, const bNodeSocket &socket) const; + + Span<SocketLog> input_logs() const + { + return input_logs_; + } + + Span<SocketLog> output_logs() const + { + return output_logs_; + } + + Span<NodeWarning> warnings() const + { + return warnings_; + } + + Vector<const GeometryAttributeInfo *> lookup_available_attributes() const; +}; + +/** Contains information that has been logged for one specific tree. */ +class TreeLog { + private: + Map<std::string, destruct_ptr<NodeLog>> node_logs_; + Map<std::string, destruct_ptr<TreeLog>> child_logs_; + + friend ModifierLog; + + public: + const NodeLog *lookup_node_log(StringRef node_name) const; + const NodeLog *lookup_node_log(const bNode &node) const; + const TreeLog *lookup_child_log(StringRef node_name) const; +}; + +/** Contains information about an entire geometry nodes evaluation. */ +class ModifierLog { + private: + LinearAllocator<> allocator_; + /* Allocators of the individual loggers. */ + Vector<std::unique_ptr<LinearAllocator<>>> logger_allocators_; + destruct_ptr<TreeLog> root_tree_logs_; + Vector<destruct_ptr<ValueLog>> logged_values_; + + public: + ModifierLog(GeoLogger &logger); + + const TreeLog &root_tree() const + { + return *root_tree_logs_; + } + + /* Utilities to find logged information for a specific context. */ + static const ModifierLog *find_root_by_node_editor_context(const SpaceNode &snode); + static const TreeLog *find_tree_by_node_editor_context(const SpaceNode &snode); + static const NodeLog *find_node_by_node_editor_context(const SpaceNode &snode, + const bNode &node); + static const SocketLog *find_socket_by_node_editor_context(const SpaceNode &snode, + const bNode &node, + const bNodeSocket &socket); + static const NodeLog *find_node_by_spreadsheet_editor_context( + const SpaceSpreadsheet &sspreadsheet); + + private: + using LogByTreeContext = Map<const DTreeContext *, TreeLog *>; + + TreeLog &lookup_or_add_tree_log(LogByTreeContext &log_by_tree_context, + const DTreeContext &tree_context); + NodeLog &lookup_or_add_node_log(LogByTreeContext &log_by_tree_context, DNode node); + SocketLog &lookup_or_add_socket_log(LogByTreeContext &log_by_tree_context, DSocket socket); +}; + +} // namespace blender::nodes::geometry_nodes_eval_log diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 2d15fcca24b..73d4a002991 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -210,7 +210,7 @@ DefNode(CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPS DefNode(CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE", BokehImage, "Bokeh Image", "" ) DefNode(CompositorNode, CMP_NODE_BOKEHBLUR, def_cmp_bokehblur, "BOKEHBLUR", BokehBlur, "Bokeh Blur", "" ) DefNode(CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH", Switch, "Switch", "" ) -DefNode(CompositorNode, CMP_NODE_SWITCH_VIEW, def_cmp_switch_view, "VIEWSWITCH", SwitchView, "View Switch", "" ) +DefNode(CompositorNode, CMP_NODE_SWITCH_VIEW, def_cmp_switch_view, "VIEWSWITCH", SwitchView, "Switch View", "" ) DefNode(CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "Color Correction", "" ) DefNode(CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" ) DefNode(CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "Keying Screen", "" ) @@ -293,8 +293,9 @@ DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLEC DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "") DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, def_geo_curve_primitive_bezier_segment, "CURVE_PRIMITIVE_BEZIER_SEGMENT", CurvePrimitiveBezierSegment, "Bezier Segment", "") -DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, def_geo_curve_primitive_circle, "CURVE_PRIMITIVE_CIRCLE", CurvePrimitiveCircle, "Circle", "") +DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, def_geo_curve_primitive_circle, "CURVE_PRIMITIVE_CIRCLE", CurvePrimitiveCircle, "Curve Circle", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_LINE, def_geo_curve_primitive_line, "CURVE_PRIMITIVE_LINE", CurvePrimitiveLine, "Curve Line", "") +DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, def_geo_curve_primitive_quadrilateral, "CURVE_PRIMITIVE_QUADRILATERAL", CurvePrimitiveQuadrilateral, "Quadrilateral", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER, 0, "CURVE_PRIMITIVE_QUADRATIC_BEZIER", CurveQuadraticBezier, "Quadratic Bezier", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_SPIRAL, 0, "CURVE_PRIMITIVE_SPIRAL", CurveSpiral, "Curve Spiral", "") @@ -303,6 +304,7 @@ DefNode(GeometryNode, GEO_NODE_CURVE_SUBDIVIDE, def_geo_curve_subdivide, "CURVE_ DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "") DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Curve Reverse", "") DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "") +DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "") DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, 0, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "") DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "") DefNode(GeometryNode, GEO_NODE_INPUT_MATERIAL, def_geo_input_material, "INPUT_MATERIAL", InputMaterial, "Material", "") @@ -310,13 +312,13 @@ DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Vi DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "") DefNode(GeometryNode, GEO_NODE_MATERIAL_ASSIGN, 0, "MATERIAL_ASSIGN", MaterialAssign, "Material Assign", "") DefNode(GeometryNode, GEO_NODE_MATERIAL_REPLACE, 0, "MATERIAL_REPLACE", MaterialReplace, "Material Replace", "") -DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Circle", "") +DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE", MeshCone, "Cone", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CUBE, 0, "MESH_PRIMITIVE_CUBE", MeshCube, "Cube", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CYLINDER, def_geo_mesh_cylinder, "MESH_PRIMITIVE_CYLINDER", MeshCylinder, "Cylinder", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_GRID, 0, "MESH_PRIMITIVE_GRID", MeshGrid, "Grid", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, 0, "MESH_PRIMITIVE_ICO_SPHERE", MeshIcoSphere, "Ico Sphere", "") -DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_LINE, def_geo_mesh_line, "MESH_PRIMITIVE_LINE", MeshLine, "Line", "") +DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_LINE, def_geo_mesh_line, "MESH_PRIMITIVE_LINE", MeshLine, "Mesh Line", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, 0, "MESH_PRIMITIVE_UV_SPHERE", MeshUVSphere, "UV Sphere", "") DefNode(GeometryNode, GEO_NODE_MESH_TO_CURVE, 0, "MESH_TO_CURVE", MeshToCurve, "Mesh to Curve", "") DefNode(GeometryNode, GEO_NODE_OBJECT_INFO, def_geo_object_info, "OBJECT_INFO", ObjectInfo, "Object Info", "") @@ -330,7 +332,7 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "") DefNode(GeometryNode, GEO_NODE_SELECT_BY_MATERIAL, 0, "SELECT_BY_MATERIAL", SelectByMaterial, "Select by Material", "") DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS", SeparateComponents, "Separate Components", "") -DefNode(GeometryNode, GEO_NODE_SUBDIVIDE, 0, "SUBDIVIDE", Subdivide, "Subdivide", "") +DefNode(GeometryNode, GEO_NODE_MESH_SUBDIVIDE, 0, "MESH_SUBDIVIDE", MeshSubdivide, "Mesh Subdivide", "") DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, 0, "SUBDIVISION_SURFACE", SubdivisionSurface, "Subdivision Surface", "") DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "") DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "") diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 19815d01278..013d196e1c8 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -205,10 +205,11 @@ static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode) } } -static bool composite_node_tree_socket_type_valid(eNodeSocketDatatype socket_type, - bNodeTreeType *UNUSED(ntreetype)) +static bool composite_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype), + bNodeSocketType *socket_type) { - return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA); + return nodeIsStaticSocketType(socket_type) && + ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA); } bNodeTreeType *ntreeType_Composite; diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc index f4cd00b88ed..07a89a1fa8c 100644 --- a/source/blender/nodes/geometry/node_geometry_tree.cc +++ b/source/blender/nodes/geometry/node_geometry_tree.cc @@ -95,21 +95,21 @@ static bool geometry_node_tree_validate_link(bNodeTree *UNUSED(ntree), bNodeLink return (link->tosock->type == link->fromsock->type); } -static bool geometry_node_tree_socket_type_valid(eNodeSocketDatatype socket_type, - bNodeTreeType *UNUSED(ntreetype)) +static bool geometry_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype), + bNodeSocketType *socket_type) { - return ELEM(socket_type, - SOCK_FLOAT, - SOCK_VECTOR, - SOCK_RGBA, - SOCK_BOOLEAN, - SOCK_INT, - SOCK_STRING, - SOCK_OBJECT, - SOCK_GEOMETRY, - SOCK_COLLECTION, - SOCK_TEXTURE, - SOCK_MATERIAL); + return nodeIsStaticSocketType(socket_type) && ELEM(socket_type->type, + SOCK_FLOAT, + SOCK_VECTOR, + SOCK_RGBA, + SOCK_BOOLEAN, + SOCK_INT, + SOCK_STRING, + SOCK_OBJECT, + SOCK_GEOMETRY, + SOCK_COLLECTION, + SOCK_TEXTURE, + SOCK_MATERIAL); } void register_node_tree_type_geo(void) diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index 79a98c5ebf0..956b7b8a005 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -70,4 +70,26 @@ void copy_point_attributes_based_on_mask(const GeometryComponent &in_component, Span<bool> masks, const bool invert); +struct CurveToPointsResults { + int result_size; + MutableSpan<float3> positions; + MutableSpan<float> radii; + MutableSpan<float> tilts; + + Map<std::string, GMutableSpan> point_attributes; + + MutableSpan<float3> tangents; + MutableSpan<float3> normals; + MutableSpan<float3> rotations; +}; +/** + * Create references for all result point cloud attributes to simplify accessing them later on. + */ +CurveToPointsResults curve_to_points_create_result_attributes(PointCloudComponent &points, + const CurveEval &curve); + +void curve_create_default_rotation_attribute(Span<float3> tangents, + Span<float3> normals, + MutableSpan<float3> rotations); + } // namespace blender::nodes diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoints.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoints.cc new file mode 100644 index 00000000000..1f878259f30 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoints.cc @@ -0,0 +1,223 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "BLI_task.hh" +#include "BLI_timeit.hh" + +#include "BKE_pointcloud.h" +#include "BKE_spline.hh" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "node_geometry_util.hh" + +static bNodeSocketTemplate geo_node_curve_endpoints_in[] = { + {SOCK_GEOMETRY, N_("Geometry")}, + {-1, ""}, +}; + +static bNodeSocketTemplate geo_node_curve_endpoints_out[] = { + {SOCK_GEOMETRY, N_("Start Points")}, + {SOCK_GEOMETRY, N_("End Points")}, + {-1, ""}, +}; + +namespace blender::nodes { + +/** + * Evaluate splines in parallel to speed up the rest of the node's execution. + */ +static void evaluate_splines(Span<SplinePtr> splines) +{ + threading::parallel_for_each(splines, [](const SplinePtr &spline) { + /* These functions fill the corresponding caches on each spline. */ + spline->evaluated_positions(); + spline->evaluated_tangents(); + spline->evaluated_normals(); + spline->evaluated_lengths(); + }); +} + +/** + * \note Use attributes from the curve component rather than the attribute data directly on the + * attribute storage to allow reading the virtual spline attributes like "cyclic" and "resolution". + */ +static void copy_spline_domain_attributes(const CurveComponent &curve_component, + Span<int> offsets, + PointCloudComponent &points) +{ + curve_component.attribute_foreach([&](StringRefNull name, const AttributeMetaData &meta_data) { + if (meta_data.domain != ATTR_DOMAIN_CURVE) { + return true; + } + GVArrayPtr spline_attribute = curve_component.attribute_get_for_read( + name, ATTR_DOMAIN_CURVE, meta_data.data_type); + + OutputAttribute result_attribute = points.attribute_try_get_for_output_only( + name, ATTR_DOMAIN_POINT, meta_data.data_type); + GMutableSpan result = result_attribute.as_span(); + + /* Only copy the attributes of splines in the offsets. */ + for (const int i : offsets.index_range()) { + spline_attribute->get(offsets[i], result[i]); + } + + result_attribute.save(); + return true; + }); +} + +/** + * Get the offsets for the splines whose endpoints we want to output. + * Filter those which are cyclic, or that evaluate to empty. + * Could be easily adapted to include a selection argument to support attribute selection. + */ +static blender::Vector<int> get_endpoint_spline_offsets(Span<SplinePtr> splines) +{ + blender::Vector<int> spline_offsets; + spline_offsets.reserve(splines.size()); + + for (const int i : splines.index_range()) { + if (!(splines[i]->is_cyclic() || splines[i]->evaluated_points_size() == 0)) { + spline_offsets.append(i); + } + } + + return spline_offsets; +} + +/** + * Copy the endpoint attributes from the correct positions at the splines at the offsets to + * the start and end attributes. + */ +static void copy_endpoint_attributes(Span<SplinePtr> splines, + Span<int> offsets, + CurveToPointsResults &start_data, + CurveToPointsResults &end_data) +{ + threading::parallel_for(offsets.index_range(), 64, [&](IndexRange range) { + for (const int i : range) { + const Spline &spline = *splines[offsets[i]]; + + /* Copy the start and end point data over. */ + start_data.positions[i] = spline.evaluated_positions().first(); + start_data.tangents[i] = spline.evaluated_tangents().first(); + start_data.normals[i] = spline.evaluated_normals().first(); + start_data.radii[i] = spline.radii().first(); + start_data.tilts[i] = spline.tilts().first(); + + end_data.positions[i] = spline.evaluated_positions().last(); + end_data.tangents[i] = spline.evaluated_tangents().last(); + end_data.normals[i] = spline.evaluated_normals().last(); + end_data.radii[i] = spline.radii().last(); + end_data.tilts[i] = spline.tilts().last(); + + /* Copy the point attribute data over. */ + for (const auto &item : start_data.point_attributes.items()) { + const StringRef name = item.key; + GMutableSpan point_span = item.value; + + BLI_assert(spline.attributes.get_for_read(name)); + GSpan spline_span = *spline.attributes.get_for_read(name); + blender::fn::GVArray_For_GSpan(spline_span).get(0, point_span[i]); + } + + for (const auto &item : end_data.point_attributes.items()) { + const StringRef name = item.key; + GMutableSpan point_span = item.value; + + BLI_assert(spline.attributes.get_for_read(name)); + GSpan spline_span = *spline.attributes.get_for_read(name); + blender::fn::GVArray_For_GSpan(spline_span).get(spline.size() - 1, point_span[i]); + } + } + }); +} + +static void geo_node_curve_endpoints_exec(GeoNodeExecParams params) +{ + GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); + + geometry_set = bke::geometry_set_realize_instances(geometry_set); + + if (!geometry_set.has_curve()) { + params.set_output("Start Points", GeometrySet()); + params.set_output("End Points", GeometrySet()); + return; + } + + const CurveComponent &curve_component = *geometry_set.get_component_for_read<CurveComponent>(); + const CurveEval &curve = *curve_component.get_for_read(); + const Span<SplinePtr> splines = curve.splines(); + curve.assert_valid_point_attributes(); + + evaluate_splines(splines); + + const Vector<int> offsets = get_endpoint_spline_offsets(splines); + const int total_size = offsets.size(); + + if (total_size == 0) { + params.set_output("Start Points", GeometrySet()); + params.set_output("End Points", GeometrySet()); + return; + } + + GeometrySet start_result = GeometrySet::create_with_pointcloud( + BKE_pointcloud_new_nomain(total_size)); + GeometrySet end_result = GeometrySet::create_with_pointcloud( + BKE_pointcloud_new_nomain(total_size)); + PointCloudComponent &start_point_component = + start_result.get_component_for_write<PointCloudComponent>(); + PointCloudComponent &end_point_component = + end_result.get_component_for_write<PointCloudComponent>(); + + CurveToPointsResults start_attributes = curve_to_points_create_result_attributes( + start_point_component, curve); + CurveToPointsResults end_attributes = curve_to_points_create_result_attributes( + end_point_component, curve); + + copy_endpoint_attributes(splines, offsets.as_span(), start_attributes, end_attributes); + copy_spline_domain_attributes(curve_component, offsets.as_span(), start_point_component); + curve_create_default_rotation_attribute( + start_attributes.tangents, start_attributes.normals, start_attributes.rotations); + curve_create_default_rotation_attribute( + end_attributes.tangents, end_attributes.normals, end_attributes.rotations); + + /* The default radius is way too large for points, divide by 10. */ + for (float &radius : start_attributes.radii) { + radius *= 0.1f; + } + for (float &radius : end_attributes.radii) { + radius *= 0.1f; + } + + params.set_output("Start Points", std::move(start_result)); + params.set_output("End Points", std::move(end_result)); +} + +} // namespace blender::nodes + +void register_node_type_geo_curve_endpoints() +{ + static bNodeType ntype; + + geo_node_type_base(&ntype, GEO_NODE_CURVE_ENDPOINTS, "Curve Endpoints", NODE_CLASS_GEOMETRY, 0); + node_type_socket_templates(&ntype, geo_node_curve_endpoints_in, geo_node_curve_endpoints_out); + ntype.geometry_node_execute = blender::nodes::geo_node_curve_endpoints_exec; + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc index 2b3ebf7f5f1..ae947b7aeed 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc @@ -83,9 +83,10 @@ static bool colinear_f3_f3_f3(const float3 p1, const float3 p2, const float3 p3) } static std::unique_ptr<CurveEval> create_point_circle_curve( - const float3 p1, const float3 p2, const float3 p3, const int resolution, float center_out[3]) + const float3 p1, const float3 p2, const float3 p3, const int resolution, float3 &r_center) { if (colinear_f3_f3_f3(p1, p2, p3)) { + r_center = float3(0); return nullptr; } @@ -118,6 +119,7 @@ static std::unique_ptr<CurveEval> create_point_circle_curve( /* If the 3 planes do not intersect at one point, just return empty geometry. */ if (!isect_plane_plane_plane_v3(plane_1, plane_2, plane_3, center)) { + r_center = float3(0); return nullptr; } @@ -141,7 +143,7 @@ static std::unique_ptr<CurveEval> create_point_circle_curve( curve->add_spline(std::move(spline)); curve->attributes.reallocate(curve->splines().size()); - copy_v3_v3(center_out, center); + r_center = center; return curve; } @@ -179,18 +181,13 @@ static void geo_node_curve_primitive_circle_exec(GeoNodeExecParams params) std::unique_ptr<CurveEval> curve; if (mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS) { - float center_point[3]; + float3 center_point; curve = create_point_circle_curve(params.extract_input<float3>("Point 1"), params.extract_input<float3>("Point 2"), params.extract_input<float3>("Point 3"), std::max(params.extract_input<int>("Resolution"), 3), center_point); - if (curve) { - params.set_output("Center", float3(center_point)); - } - else { - params.set_output("Center", float3(0, 0, 0)); - } + params.set_output("Center", center_point); } else if (mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_RADIUS) { curve = create_radius_circle_curve(std::max(params.extract_input<int>("Resolution"), 3), @@ -210,7 +207,8 @@ static void geo_node_curve_primitive_circle_exec(GeoNodeExecParams params) void register_node_type_geo_curve_primitive_circle() { static bNodeType ntype; - geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, "Circle", NODE_CLASS_GEOMETRY, 0); + geo_node_type_base( + &ntype, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, "Curve Circle", NODE_CLASS_GEOMETRY, 0); node_type_socket_templates( &ntype, geo_node_curve_primitive_circle_in, geo_node_curve_primitive_circle_out); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc index 7aeb077d1d6..419a7af1ba0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc @@ -23,9 +23,9 @@ static bNodeSocketTemplate geo_node_curve_primitive_line_in[] = { {SOCK_VECTOR, N_("Start"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION}, - {SOCK_VECTOR, N_("End"), 0.0f, 2.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION}, - {SOCK_VECTOR, N_("Direction"), 0.0f, 1.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, - {SOCK_FLOAT, N_("Length"), 2.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {SOCK_VECTOR, N_("End"), 0.0f, 0.0f, 1.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION}, + {SOCK_VECTOR, N_("Direction"), 0.0f, 0.0f, 1.0f, 0.0f, -FLT_MAX, FLT_MAX}, + {SOCK_FLOAT, N_("Length"), 1.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, {-1, ""}, }; @@ -95,7 +95,7 @@ static std::unique_ptr<CurveEval> create_direction_line_curve(const float3 start spline->resize(2); MutableSpan<float3> positions = spline->positions(); positions[0] = start; - positions[1] = direction.normalized() * length; + positions[1] = direction.normalized() * length + start; spline->radii().fill(1.0f); spline->tilts().fill(0.0f); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc new file mode 100644 index 00000000000..5f3f159c305 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc @@ -0,0 +1,241 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "BKE_spline.hh" +#include "UI_interface.h" +#include "UI_resources.h" +#include "node_geometry_util.hh" + +static bNodeSocketTemplate geo_node_curve_primitive_quadrilateral_in[] = { + {SOCK_FLOAT, N_("Width"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Height"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Bottom Width"), 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Top Width"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Offset"), 1.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Bottom Height"), 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Top Height"), 1.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {SOCK_VECTOR, N_("Point 1"), -1.0f, 1.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {SOCK_VECTOR, N_("Point 2"), 1.0f, 1.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {SOCK_VECTOR, N_("Point 3"), 1.0f, -1.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {SOCK_VECTOR, N_("Point 4"), -1.0f, -1.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_DISTANCE}, + {-1, ""}, +}; + +static bNodeSocketTemplate geo_node_curve_primitive_quadrilateral_out[] = { + {SOCK_GEOMETRY, N_("Curve")}, + {-1, ""}, +}; + +static void geo_node_curve_primitive_quadrilateral_layout(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); +} + +static void geo_node_curve_primitive_quadrilateral_init(bNodeTree *UNUSED(tree), bNode *node) +{ + NodeGeometryCurvePrimitiveQuad *data = (NodeGeometryCurvePrimitiveQuad *)MEM_callocN( + sizeof(NodeGeometryCurvePrimitiveQuad), __func__); + data->mode = GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE; + node->storage = data; +} + +namespace blender::nodes { + +static void geo_node_curve_primitive_quadrilateral_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeGeometryCurvePrimitiveQuad &node_storage = *(NodeGeometryCurvePrimitiveQuad *)node->storage; + GeometryNodeCurvePrimitiveQuadMode mode = static_cast<GeometryNodeCurvePrimitiveQuadMode>( + node_storage.mode); + + bNodeSocket *width = ((bNodeSocket *)node->inputs.first); + bNodeSocket *height = width->next; + bNodeSocket *bottom = height->next; + bNodeSocket *top = bottom->next; + bNodeSocket *offset = top->next; + bNodeSocket *bottom_height = offset->next; + bNodeSocket *top_height = bottom_height->next; + bNodeSocket *p1 = top_height->next; + bNodeSocket *p2 = p1->next; + bNodeSocket *p3 = p2->next; + bNodeSocket *p4 = p3->next; + + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { + nodeSetSocketAvailability(sock, false); + } + + if (mode == GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE) { + nodeSetSocketAvailability(width, true); + nodeSetSocketAvailability(height, true); + } + else if (mode == GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_PARALLELOGRAM) { + nodeSetSocketAvailability(width, true); + nodeSetSocketAvailability(height, true); + nodeSetSocketAvailability(offset, true); + } + else if (mode == GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_TRAPEZOID) { + nodeSetSocketAvailability(bottom, true); + nodeSetSocketAvailability(top, true); + nodeSetSocketAvailability(offset, true); + nodeSetSocketAvailability(height, true); + } + else if (mode == GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_KITE) { + nodeSetSocketAvailability(width, true); + nodeSetSocketAvailability(bottom_height, true); + nodeSetSocketAvailability(top_height, true); + } + else if (mode == GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_POINTS) { + nodeSetSocketAvailability(p1, true); + nodeSetSocketAvailability(p2, true); + nodeSetSocketAvailability(p3, true); + nodeSetSocketAvailability(p4, true); + } +} + +static void create_rectangle_curve(MutableSpan<float3> positions, + const float height, + const float width) +{ + positions[0] = float3(width / 2.0f, -height / 2.0f, 0.0f); + positions[1] = float3(-width / 2.0f, -height / 2.0f, 0.0f); + positions[2] = float3(-width / 2.0f, height / 2.0f, 0.0f); + positions[3] = float3(width / 2.0f, height / 2.0f, 0.0f); +} + +static void create_points_curve(MutableSpan<float3> positions, + const float3 &p1, + const float3 &p2, + const float3 &p3, + const float3 &p4) +{ + positions[0] = p1; + positions[1] = p2; + positions[2] = p3; + positions[3] = p4; +} + +static void create_parallelogram_curve(MutableSpan<float3> positions, + const float height, + const float width, + const float offset) +{ + positions[0] = float3(width / 2.0f - offset / 2.0f, -height / 2.0f, 0.0f); + positions[1] = float3(-width / 2.0f - offset / 2.0f, -height / 2.0f, 0.0f); + positions[2] = float3(-width / 2.0f + offset / 2.0f, height / 2.0f, 0.0f); + positions[3] = float3(width / 2.0f + offset / 2.0f, height / 2.0f, 0.0f); +} +static void create_trapezoid_curve(MutableSpan<float3> positions, + const float bottom, + const float top, + const float offset, + const float height) +{ + positions[0] = float3(bottom / 2.0f, -height / 2.0f, 0.0f); + positions[1] = float3(-bottom / 2.0f, -height / 2.0f, 0.0f); + positions[2] = float3(-top / 2.0f + offset, height / 2.0f, 0.0f); + positions[3] = float3(top / 2.0f + offset, height / 2.0f, 0.0f); +} + +static void create_kite_curve(MutableSpan<float3> positions, + const float width, + const float bottom_height, + const float top_height) +{ + positions[0] = float3(-width / 2.0f, 0, 0); + positions[1] = float3(0, top_height, 0); + positions[2] = float3(width / 2, 0, 0); + positions[3] = float3(0, -bottom_height, 0); +} + +static void geo_node_curve_primitive_quadrilateral_exec(GeoNodeExecParams params) +{ + const NodeGeometryCurvePrimitiveQuad &node_storage = + *(NodeGeometryCurvePrimitiveQuad *)(params.node()).storage; + const GeometryNodeCurvePrimitiveQuadMode mode = static_cast<GeometryNodeCurvePrimitiveQuadMode>( + node_storage.mode); + + std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>(); + std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>(); + spline->resize(4); + spline->radii().fill(1.0f); + spline->tilts().fill(0.0f); + spline->set_cyclic(true); + MutableSpan<float3> positions = spline->positions(); + + switch (mode) { + case GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE: + create_rectangle_curve(positions, + std::max(params.extract_input<float>("Height"), 0.0f), + std::max(params.extract_input<float>("Width"), 0.0f)); + break; + + case GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_PARALLELOGRAM: + create_parallelogram_curve(positions, + std::max(params.extract_input<float>("Height"), 0.0f), + std::max(params.extract_input<float>("Width"), 0.0f), + params.extract_input<float>("Offset")); + break; + case GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_TRAPEZOID: + create_trapezoid_curve(positions, + std::max(params.extract_input<float>("Bottom Width"), 0.0f), + std::max(params.extract_input<float>("Top Width"), 0.0f), + params.extract_input<float>("Offset"), + std::max(params.extract_input<float>("Height"), 0.0f)); + break; + case GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_KITE: + create_kite_curve(positions, + std::max(params.extract_input<float>("Width"), 0.0f), + std::max(params.extract_input<float>("Bottom Height"), 0.0f), + params.extract_input<float>("Top Height")); + break; + case GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_POINTS: + create_points_curve(positions, + params.extract_input<float3>("Point 1"), + params.extract_input<float3>("Point 2"), + params.extract_input<float3>("Point 3"), + params.extract_input<float3>("Point 4")); + break; + default: + params.set_output("Curve", GeometrySet()); + return; + } + + curve->add_spline(std::move(spline)); + curve->attributes.reallocate(curve->splines().size()); + params.set_output("Curve", GeometrySet::create_with_curve(curve.release())); +} + +} // namespace blender::nodes + +void register_node_type_geo_curve_primitive_quadrilateral() +{ + static bNodeType ntype; + geo_node_type_base( + &ntype, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, "Quadrilateral", NODE_CLASS_GEOMETRY, 0); + node_type_socket_templates(&ntype, + geo_node_curve_primitive_quadrilateral_in, + geo_node_curve_primitive_quadrilateral_out); + ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_quadrilateral_exec; + ntype.draw_buttons = geo_node_curve_primitive_quadrilateral_layout; + node_type_update(&ntype, blender::nodes::geo_node_curve_primitive_quadrilateral_update); + node_type_init(&ntype, geo_node_curve_primitive_quadrilateral_init); + node_type_storage(&ntype, + "NodeGeometryCurvePrimitiveQuad", + node_free_standard_storage, + node_copy_standard_storage); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc index 367da3bc3c2..2e2bb247e2b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc @@ -19,7 +19,7 @@ #include "node_geometry_util.hh" static bNodeSocketTemplate geo_node_curve_primitive_star_in[] = { - {SOCK_INT, N_("Points"), 8.0f, 0.0f, 0.0f, 0.0f, 4, 256, PROP_UNSIGNED}, + {SOCK_INT, N_("Points"), 8.0f, 0.0f, 0.0f, 0.0f, 3, 256, PROP_UNSIGNED}, {SOCK_FLOAT, N_("Inner Radius"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, {SOCK_FLOAT, N_("Outer Radius"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, {SOCK_FLOAT, N_("Twist"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_ANGLE}, @@ -64,7 +64,7 @@ static void geo_node_curve_primitive_star_exec(GeoNodeExecParams params) std::max(params.extract_input<float>("Inner Radius"), 0.0f), std::max(params.extract_input<float>("Outer Radius"), 0.0f), params.extract_input<float>("Twist"), - std::max(params.extract_input<int>("Points"), 4)); + std::max(params.extract_input<int>("Points"), 3)); params.set_output("Curve", GeometrySet::create_with_curve(curve.release())); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc index fc65d1754e9..ad0c453c2af 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc @@ -87,6 +87,23 @@ static SplinePtr resample_spline(const Spline &input_spline, const int count) input_spline.tilts().first(), input_spline.radii().first()); output_spline->attributes.reallocate(1); + input_spline.attributes.foreach_attribute( + [&](StringRefNull name, const AttributeMetaData &meta_data) { + std::optional<GSpan> src = input_spline.attributes.get_for_read(name); + BLI_assert(src); + if (!output_spline->attributes.create(name, meta_data.data_type)) { + BLI_assert_unreachable(); + return false; + } + std::optional<GMutableSpan> dst = output_spline->attributes.get_for_write(name); + if (!dst) { + BLI_assert_unreachable(); + return false; + } + src->type().copy_assign(src->data(), dst->data()); + return true; + }, + ATTR_DOMAIN_POINT); return output_spline; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index e37822bd262..bb8f560f92d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -118,22 +118,6 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams ¶ms, return {0}; } -/** - * \note This doesn't store a map for spline domain attributes. - */ -struct ResultAttributes { - int result_size; - MutableSpan<float3> positions; - MutableSpan<float> radii; - MutableSpan<float> tilts; - - Map<std::string, GMutableSpan> point_attributes; - - MutableSpan<float3> tangents; - MutableSpan<float3> normals; - MutableSpan<float3> rotations; -}; - static GMutableSpan create_attribute_and_retrieve_span(PointCloudComponent &points, const StringRef name, const CustomDataType data_type) @@ -153,13 +137,10 @@ static MutableSpan<T> create_attribute_and_retrieve_span(PointCloudComponent &po return attribute.typed<T>(); } -/** - * Create references for all result point cloud attributes to simplify accessing them later on. - */ -static ResultAttributes create_point_attributes(PointCloudComponent &points, - const CurveEval &curve) +CurveToPointsResults curve_to_points_create_result_attributes(PointCloudComponent &points, + const CurveEval &curve) { - ResultAttributes attributes; + CurveToPointsResults attributes; attributes.result_size = points.attribute_domain_size(ATTR_DOMAIN_POINT); @@ -190,7 +171,7 @@ static ResultAttributes create_point_attributes(PointCloudComponent &points, */ static void copy_evaluated_point_attributes(Span<SplinePtr> splines, Span<int> offsets, - ResultAttributes &data) + CurveToPointsResults &data) { threading::parallel_for(splines.index_range(), 64, [&](IndexRange range) { for (const int i : range) { @@ -221,7 +202,7 @@ static void copy_evaluated_point_attributes(Span<SplinePtr> splines, static void copy_uniform_sample_point_attributes(Span<SplinePtr> splines, Span<int> offsets, - ResultAttributes &data) + CurveToPointsResults &data) { threading::parallel_for(splines.index_range(), 64, [&](IndexRange range) { for (const int i : range) { @@ -307,13 +288,14 @@ static void copy_spline_domain_attributes(const CurveComponent &curve_component, }); } -static void create_default_rotation_attribute(ResultAttributes &data) +void curve_create_default_rotation_attribute(Span<float3> tangents, + Span<float3> normals, + MutableSpan<float3> rotations) { - threading::parallel_for(IndexRange(data.result_size), 512, [&](IndexRange range) { + threading::parallel_for(IndexRange(rotations.size()), 512, [&](IndexRange range) { for (const int i : range) { - data.rotations[i] = float4x4::from_normalized_axis_data( - {0, 0, 0}, data.normals[i], data.tangents[i]) - .to_euler(); + rotations[i] = + float4x4::from_normalized_axis_data({0, 0, 0}, normals[i], tangents[i]).to_euler(); } }); } @@ -348,8 +330,8 @@ static void geo_node_curve_to_points_exec(GeoNodeExecParams params) GeometrySet result = GeometrySet::create_with_pointcloud(BKE_pointcloud_new_nomain(total_size)); PointCloudComponent &point_component = result.get_component_for_write<PointCloudComponent>(); - ResultAttributes new_attributes = create_point_attributes(point_component, curve); - + CurveToPointsResults new_attributes = curve_to_points_create_result_attributes(point_component, + curve); switch (mode) { case GEO_NODE_CURVE_SAMPLE_COUNT: case GEO_NODE_CURVE_SAMPLE_LENGTH: @@ -361,7 +343,8 @@ static void geo_node_curve_to_points_exec(GeoNodeExecParams params) } copy_spline_domain_attributes(curve_component, offsets, point_component); - create_default_rotation_attribute(new_attributes); + curve_create_default_rotation_attribute( + new_attributes.tangents, new_attributes.normals, new_attributes.rotations); /* The default radius is way too large for points, divide by 10. */ for (float &radius : new_attributes.radii) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index 2915a17d2c8..667e1c931bd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -228,7 +228,8 @@ void register_node_type_geo_mesh_primitive_circle() { static bNodeType ntype; - geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CIRCLE, "Circle", NODE_CLASS_GEOMETRY, 0); + geo_node_type_base( + &ntype, GEO_NODE_MESH_PRIMITIVE_CIRCLE, "Mesh Circle", NODE_CLASS_GEOMETRY, 0); node_type_socket_templates( &ntype, geo_node_mesh_primitive_circle_in, geo_node_mesh_primitive_circle_out); node_type_init(&ntype, geo_node_mesh_primitive_circle_init); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc index e841455e58c..a193c05daa1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc @@ -177,7 +177,7 @@ void register_node_type_geo_mesh_primitive_line() { static bNodeType ntype; - geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_LINE, "Line", NODE_CLASS_GEOMETRY, 0); + geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_LINE, "Mesh Line", NODE_CLASS_GEOMETRY, 0); node_type_socket_templates( &ntype, geo_node_mesh_primitive_line_in, geo_node_mesh_primitive_line_out); node_type_init(&ntype, geo_node_mesh_primitive_line_init); diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc index 63aafe53e3b..245d7800621 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc @@ -14,8 +14,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// #include "MEM_guardedalloc.h" - #include "BKE_mesh.h" #include "BKE_subdiv.h" #include "BKE_subdiv_mesh.h" @@ -25,20 +23,20 @@ #include "node_geometry_util.hh" -static bNodeSocketTemplate geo_node_subdivide_in[] = { +static bNodeSocketTemplate geo_node_mesh_subdivide_in[] = { {SOCK_GEOMETRY, N_("Geometry")}, {SOCK_INT, N_("Level"), 1, 0, 0, 0, 0, 6}, {-1, ""}, }; -static bNodeSocketTemplate geo_node_subdivide_out[] = { +static bNodeSocketTemplate geo_node_mesh_subdivide_out[] = { {SOCK_GEOMETRY, N_("Geometry")}, {-1, ""}, }; namespace blender::nodes { -static void geo_node_subdivide_exec(GeoNodeExecParams params) +static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); geometry_set = geometry_set_realize_instances(geometry_set); @@ -102,12 +100,12 @@ static void geo_node_subdivide_exec(GeoNodeExecParams params) } // namespace blender::nodes -void register_node_type_geo_subdivide() +void register_node_type_geo_mesh_subdivide() { static bNodeType ntype; - geo_node_type_base(&ntype, GEO_NODE_SUBDIVIDE, "Subdivide", NODE_CLASS_GEOMETRY, 0); - node_type_socket_templates(&ntype, geo_node_subdivide_in, geo_node_subdivide_out); - ntype.geometry_node_execute = blender::nodes::geo_node_subdivide_exec; + geo_node_type_base(&ntype, GEO_NODE_MESH_SUBDIVIDE, "Mesh Subdivide", NODE_CLASS_GEOMETRY, 0); + node_type_socket_templates(&ntype, geo_node_mesh_subdivide_in, geo_node_mesh_subdivide_out); + ntype.geometry_node_execute = blender::nodes::geo_node_mesh_subdivide_exec; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/intern/geometry_nodes_eval_log.cc b/source/blender/nodes/intern/geometry_nodes_eval_log.cc new file mode 100644 index 00000000000..85182b67c8a --- /dev/null +++ b/source/blender/nodes/intern/geometry_nodes_eval_log.cc @@ -0,0 +1,330 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "NOD_geometry_nodes_eval_log.hh" + +#include "BKE_geometry_set_instances.hh" + +#include "DNA_modifier_types.h" +#include "DNA_space_types.h" + +namespace blender::nodes::geometry_nodes_eval_log { + +using fn::CPPType; + +ModifierLog::ModifierLog(GeoLogger &logger) +{ + root_tree_logs_ = allocator_.construct<TreeLog>(); + + LogByTreeContext log_by_tree_context; + + /* Combine all the local loggers that have been used by separate threads. */ + for (LocalGeoLogger &local_logger : logger) { + /* Take ownership of the allocator. */ + logger_allocators_.append(std::move(local_logger.allocator_)); + + for (ValueOfSockets &value_of_sockets : local_logger.values_) { + ValueLog *value_log = value_of_sockets.value.get(); + + /* Take centralized ownership of the logged value. It might be referenced by multiple + * sockets. */ + logged_values_.append(std::move(value_of_sockets.value)); + + for (const DSocket &socket : value_of_sockets.sockets) { + SocketLog &socket_log = this->lookup_or_add_socket_log(log_by_tree_context, socket); + socket_log.value_ = value_log; + } + } + + for (NodeWithWarning &node_with_warning : local_logger.node_warnings_) { + NodeLog &node_log = this->lookup_or_add_node_log(log_by_tree_context, + node_with_warning.node); + node_log.warnings_.append(node_with_warning.warning); + } + } +} + +TreeLog &ModifierLog::lookup_or_add_tree_log(LogByTreeContext &log_by_tree_context, + const DTreeContext &tree_context) +{ + TreeLog *tree_log = log_by_tree_context.lookup_default(&tree_context, nullptr); + if (tree_log != nullptr) { + return *tree_log; + } + + const DTreeContext *parent_context = tree_context.parent_context(); + if (parent_context == nullptr) { + return *root_tree_logs_.get(); + } + TreeLog &parent_log = this->lookup_or_add_tree_log(log_by_tree_context, *parent_context); + destruct_ptr<TreeLog> owned_tree_log = allocator_.construct<TreeLog>(); + tree_log = owned_tree_log.get(); + log_by_tree_context.add_new(&tree_context, tree_log); + parent_log.child_logs_.add_new(tree_context.parent_node()->name(), std::move(owned_tree_log)); + return *tree_log; +} + +NodeLog &ModifierLog::lookup_or_add_node_log(LogByTreeContext &log_by_tree_context, DNode node) +{ + TreeLog &tree_log = this->lookup_or_add_tree_log(log_by_tree_context, *node.context()); + NodeLog &node_log = *tree_log.node_logs_.lookup_or_add_cb(node->name(), [&]() { + destruct_ptr<NodeLog> node_log = allocator_.construct<NodeLog>(); + node_log->input_logs_.resize(node->inputs().size()); + node_log->output_logs_.resize(node->outputs().size()); + return node_log; + }); + return node_log; +} + +SocketLog &ModifierLog::lookup_or_add_socket_log(LogByTreeContext &log_by_tree_context, + DSocket socket) +{ + NodeLog &node_log = this->lookup_or_add_node_log(log_by_tree_context, socket.node()); + MutableSpan<SocketLog> socket_logs = socket->is_input() ? node_log.input_logs_ : + node_log.output_logs_; + SocketLog &socket_log = socket_logs[socket->index()]; + return socket_log; +} + +const NodeLog *TreeLog::lookup_node_log(StringRef node_name) const +{ + const destruct_ptr<NodeLog> *node_log = node_logs_.lookup_ptr_as(node_name); + if (node_log == nullptr) { + return nullptr; + } + return node_log->get(); +} + +const NodeLog *TreeLog::lookup_node_log(const bNode &node) const +{ + return this->lookup_node_log(node.name); +} + +const TreeLog *TreeLog::lookup_child_log(StringRef node_name) const +{ + const destruct_ptr<TreeLog> *tree_log = child_logs_.lookup_ptr_as(node_name); + if (tree_log == nullptr) { + return nullptr; + } + return tree_log->get(); +} + +const SocketLog *NodeLog::lookup_socket_log(eNodeSocketInOut in_out, int index) const +{ + BLI_assert(index >= 0); + Span<SocketLog> socket_logs = (in_out == SOCK_IN) ? input_logs_ : output_logs_; + if (index >= socket_logs.size()) { + return nullptr; + } + return &socket_logs[index]; +} + +const SocketLog *NodeLog::lookup_socket_log(const bNode &node, const bNodeSocket &socket) const +{ + ListBase sockets = socket.in_out == SOCK_IN ? node.inputs : node.outputs; + int index = BLI_findindex(&sockets, &socket); + return this->lookup_socket_log((eNodeSocketInOut)socket.in_out, index); +} + +GeometryValueLog::GeometryValueLog(const GeometrySet &geometry_set, bool log_full_geometry) +{ + bke::geometry_set_instances_attribute_foreach( + geometry_set, + [&](StringRefNull attribute_name, const AttributeMetaData &meta_data) { + this->attributes_.append({attribute_name, meta_data.domain, meta_data.data_type}); + return true; + }, + 8); + for (const GeometryComponent *component : geometry_set.get_components_for_read()) { + component_types_.append(component->type()); + } + if (log_full_geometry) { + full_geometry_ = std::make_unique<GeometrySet>(geometry_set); + full_geometry_->ensure_owns_direct_data(); + } +} + +Vector<const GeometryAttributeInfo *> NodeLog::lookup_available_attributes() const +{ + Vector<const GeometryAttributeInfo *> attributes; + Set<StringRef> names; + for (const SocketLog &socket_log : input_logs_) { + const ValueLog *value_log = socket_log.value(); + if (const GeometryValueLog *geo_value_log = dynamic_cast<const GeometryValueLog *>( + value_log)) { + for (const GeometryAttributeInfo &attribute : geo_value_log->attributes()) { + if (names.add(attribute.name)) { + attributes.append(&attribute); + } + } + } + } + return attributes; +} + +const ModifierLog *ModifierLog::find_root_by_node_editor_context(const SpaceNode &snode) +{ + if (snode.id == nullptr) { + return nullptr; + } + if (GS(snode.id->name) != ID_OB) { + return nullptr; + } + Object *object = (Object *)snode.id; + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->type == eModifierType_Nodes) { + NodesModifierData *nmd = (NodesModifierData *)md; + if (nmd->node_group == snode.nodetree) { + return (ModifierLog *)nmd->runtime_eval_log; + } + } + } + return nullptr; +} + +const TreeLog *ModifierLog::find_tree_by_node_editor_context(const SpaceNode &snode) +{ + const ModifierLog *eval_log = ModifierLog::find_root_by_node_editor_context(snode); + if (eval_log == nullptr) { + return nullptr; + } + Vector<bNodeTreePath *> tree_path_vec = snode.treepath; + if (tree_path_vec.is_empty()) { + return nullptr; + } + TreeLog *current = eval_log->root_tree_logs_.get(); + for (bNodeTreePath *path : tree_path_vec.as_span().drop_front(1)) { + destruct_ptr<TreeLog> *tree_log = current->child_logs_.lookup_ptr_as(path->node_name); + if (tree_log == nullptr) { + return nullptr; + } + current = tree_log->get(); + } + return current; +} + +const NodeLog *ModifierLog::find_node_by_node_editor_context(const SpaceNode &snode, + const bNode &node) +{ + const TreeLog *tree_log = ModifierLog::find_tree_by_node_editor_context(snode); + if (tree_log == nullptr) { + return nullptr; + } + return tree_log->lookup_node_log(node); +} + +const SocketLog *ModifierLog::find_socket_by_node_editor_context(const SpaceNode &snode, + const bNode &node, + const bNodeSocket &socket) +{ + const NodeLog *node_log = ModifierLog::find_node_by_node_editor_context(snode, node); + if (node_log == nullptr) { + return nullptr; + } + return node_log->lookup_socket_log(node, socket); +} + +const NodeLog *ModifierLog::find_node_by_spreadsheet_editor_context( + const SpaceSpreadsheet &sspreadsheet) +{ + Vector<SpreadsheetContext *> context_path = sspreadsheet.context_path; + if (context_path.size() <= 2) { + return nullptr; + } + if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) { + return nullptr; + } + if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) { + return nullptr; + } + for (SpreadsheetContext *context : context_path.as_span().drop_front(2)) { + if (context->type != SPREADSHEET_CONTEXT_NODE) { + return nullptr; + } + } + Span<SpreadsheetContextNode *> node_contexts = + context_path.as_span().drop_front(2).cast<SpreadsheetContextNode *>(); + + Object *object = ((SpreadsheetContextObject *)context_path[0])->object; + StringRefNull modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name; + if (object == nullptr) { + return nullptr; + } + + const ModifierLog *eval_log = nullptr; + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->type == eModifierType_Nodes) { + if (md->name == modifier_name) { + NodesModifierData *nmd = (NodesModifierData *)md; + eval_log = (const ModifierLog *)nmd->runtime_eval_log; + break; + } + } + } + if (eval_log == nullptr) { + return nullptr; + } + + const TreeLog *tree_log = &eval_log->root_tree(); + for (SpreadsheetContextNode *context : node_contexts.drop_back(1)) { + tree_log = tree_log->lookup_child_log(context->node_name); + if (tree_log == nullptr) { + return nullptr; + } + } + const NodeLog *node_log = tree_log->lookup_node_log(node_contexts.last()->node_name); + return node_log; +} + +void LocalGeoLogger::log_value_for_sockets(Span<DSocket> sockets, GPointer value) +{ + const CPPType &type = *value.type(); + Span<DSocket> copied_sockets = allocator_->construct_array_copy(sockets); + if (type.is<GeometrySet>()) { + bool log_full_geometry = false; + for (const DSocket &socket : sockets) { + if (main_logger_->log_full_geometry_sockets_.contains(socket)) { + log_full_geometry = true; + break; + } + } + + const GeometrySet &geometry_set = *value.get<GeometrySet>(); + destruct_ptr<GeometryValueLog> value_log = allocator_->construct<GeometryValueLog>( + geometry_set, log_full_geometry); + values_.append({copied_sockets, std::move(value_log)}); + } + else { + void *buffer = allocator_->allocate(type.size(), type.alignment()); + type.copy_construct(value.get(), buffer); + destruct_ptr<GenericValueLog> value_log = allocator_->construct<GenericValueLog>( + GMutablePointer{type, buffer}); + values_.append({copied_sockets, std::move(value_log)}); + } +} + +void LocalGeoLogger::log_multi_value_socket(DSocket socket, Span<GPointer> values) +{ + /* Doesn't have to be logged currently. */ + UNUSED_VARS(socket, values); +} + +void LocalGeoLogger::log_node_warning(DNode node, NodeWarningType type, std::string message) +{ + node_warnings_.append({node, {type, std::move(message)}}); +} + +} // namespace blender::nodes::geometry_nodes_eval_log diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index fe11318c29d..b8c89d1db37 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -127,7 +127,7 @@ static bNodeSocket *group_verify_socket( bNodeSocket *sock; for (sock = verify_lb->first; sock; sock = sock->next) { - if (sock->typeinfo == iosock->typeinfo && STREQ(sock->identifier, iosock->identifier)) { + if (STREQ(sock->identifier, iosock->identifier)) { break; } } @@ -137,6 +137,13 @@ static bNodeSocket *group_verify_socket( const int mask = SOCK_HIDE_VALUE; sock->flag = (sock->flag & ~mask) | (iosock->flag & mask); + /* Update socket type if necessary */ + if (sock->typeinfo != iosock->typeinfo) { + nodeModifySocketType(ntree, gnode, sock, iosock->idname); + /* Flag the tree to make sure link validity is updated after type changes. */ + ntree->update |= NTREE_UPDATE_LINKS; + } + if (iosock->typeinfo->interface_verify_socket) { iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface"); } diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index 17a13f2d1b0..bfd1ad02d36 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -16,8 +16,6 @@ #include "DNA_modifier_types.h" -#include "BKE_node_ui_storage.hh" - #include "DEG_depsgraph_query.h" #include "NOD_geometry_exec.hh" @@ -26,21 +24,17 @@ #include "node_geometry_util.hh" +using blender::nodes::geometry_nodes_eval_log::LocalGeoLogger; + namespace blender::nodes { void GeoNodeExecParams::error_message_add(const NodeWarningType type, std::string message) const { - bNodeTree *btree_cow = provider_->dnode->btree(); - BLI_assert(btree_cow != nullptr); - if (btree_cow == nullptr) { + if (provider_->logger == nullptr) { return; } - bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow); - - const NodeTreeEvaluationContext context(*provider_->self_object, *provider_->modifier); - - BKE_nodetree_error_message_add( - *btree_original, context, *provider_->dnode->bnode(), type, std::move(message)); + LocalGeoLogger &local_logger = provider_->logger->local(); + local_logger.log_node_warning(provider_->dnode, type, std::move(message)); } const bNodeSocket *GeoNodeExecParams::find_available_socket(const StringRef name) const diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 9f0a145ace2..8fdad0bb242 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -117,7 +117,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, } if (sock) { if (sock->type != stemp->type) { - nodeModifySocketType(ntree, node, sock, stemp->type, stemp->subtype); + nodeModifySocketTypeStatic(ntree, node, sock, stemp->type, stemp->subtype); } sock->flag |= stemp->flag; } @@ -533,12 +533,14 @@ static bNodeSocketType *make_standard_socket_type(int type, int subtype) { const char *socket_idname = nodeStaticSocketType(type, subtype); const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype); + const char *socket_label = nodeStaticSocketLabel(type, subtype); bNodeSocketType *stype; StructRNA *srna; stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); + BLI_strncpy(stype->label, socket_label, sizeof(stype->label)); /* set the RNA type * uses the exact same identifier as the socket type idname */ diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 9bf07392c11..7367f73d171 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -184,10 +184,11 @@ static bool shader_validate_link(bNodeTree *UNUSED(ntree), bNodeLink *link) return true; } -static bool shader_node_tree_socket_type_valid(eNodeSocketDatatype socket_type, - bNodeTreeType *UNUSED(ntreetype)) +static bool shader_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype), + bNodeSocketType *socket_type) { - return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER); + return nodeIsStaticSocketType(socket_type) && + ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER); } bNodeTreeType *ntreeType_Shader; diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 2ae722e3cd8..f771b4934b2 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -152,10 +152,11 @@ static void update(bNodeTree *ntree) } } -static bool texture_node_tree_socket_type_valid(eNodeSocketDatatype socket_type, - bNodeTreeType *UNUSED(ntreetype)) +static bool texture_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype), + bNodeSocketType *socket_type) { - return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA); + return nodeIsStaticSocketType(socket_type) && + ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA); } bNodeTreeType *ntreeType_Texture; diff --git a/source/blender/python/gpu/gpu_py_uniformbuffer.c b/source/blender/python/gpu/gpu_py_uniformbuffer.c index edcec486398..cfef20e2e4d 100644 --- a/source/blender/python/gpu/gpu_py_uniformbuffer.c +++ b/source/blender/python/gpu/gpu_py_uniformbuffer.c @@ -104,7 +104,7 @@ static PyObject *pygpu_uniformbuffer__tp_new(PyTypeObject *UNUSED(self), } PyDoc_STRVAR(pygpu_uniformbuffer_update_doc, - ".. method::update(data)\n" + ".. method:: update(data)\n" "\n" " Update the data of the uniform buffer object.\n"); static PyObject *pygpu_uniformbuffer_update(BPyGPUUniformBuf *self, PyObject *obj) diff --git a/source/blender/python/intern/bpy_rna_id_collection.c b/source/blender/python/intern/bpy_rna_id_collection.c index ac061c3dd60..66044311321 100644 --- a/source/blender/python/intern/bpy_rna_id_collection.c +++ b/source/blender/python/intern/bpy_rna_id_collection.c @@ -130,7 +130,7 @@ static int foreach_libblock_id_user_map_callback(LibraryIDLinkCallbackData *cb_d } PyDoc_STRVAR(bpy_user_map_doc, - ".. method:: user_map([subset=(id1, id2, ...)], key_types={..}, value_types={..})\n" + ".. method:: user_map(subset, key_types, value_types)\n" "\n" " Returns a mapping of all ID data-blocks in current ``bpy.data`` to a set of all " "datablocks using them.\n" @@ -277,7 +277,7 @@ error: } PyDoc_STRVAR(bpy_batch_remove_doc, - ".. method:: batch_remove(ids=(id1, id2, ...))\n" + ".. method:: batch_remove(ids)\n" "\n" " Remove (delete) several IDs at once.\n" "\n" diff --git a/source/blender/python/intern/bpy_utils_previews.c b/source/blender/python/intern/bpy_utils_previews.c index 7a826d99a3d..6a46d2a1a96 100644 --- a/source/blender/python/intern/bpy_utils_previews.c +++ b/source/blender/python/intern/bpy_utils_previews.c @@ -59,7 +59,6 @@ PyDoc_STRVAR( " :type name: string\n" " :return: The Preview matching given name, or a new empty one.\n" " :rtype: :class:`bpy.types.ImagePreview`\n" - " :rtype: :class:`bpy.types.ImagePreview`\n" /* This is only true when accessed via 'bpy.utils.previews.ImagePreviewCollection.load', * however this is the public API, allow this minor difference to the internal version here. */ " :raises KeyError: if ``name`` already exists."); diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index 4ad0264582f..c2223b023ad 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -149,7 +149,7 @@ static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args) } PyDoc_STRVAR(C_Vector_Range_doc, - ".. classmethod:: Range(start=0, stop, step=1)\n" + ".. classmethod:: Range(start, stop, step=1)\n" "\n" " Create a filled with a range of values.\n" "\n" diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index fd65bb12044..d5653f87c2b 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -340,10 +340,10 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, float co_high[3], dir_high[3]; hits[i].index = -1; - /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */ + /* TODO: we should use FLT_MAX here, but sweep-sphere code isn't prepared for that. */ hits[i].dist = BVH_RAYCAST_DIST_MAX; - /* transform the ray from the world space to the highpoly space */ + /* Transform the ray from the world space to the `highpoly` space. */ mul_v3_m4v3(co_high, highpoly[i].imat, co); /* rotates */ @@ -555,10 +555,10 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, TriTessFace *tris_cage = NULL; TriTessFace **tris_high; - /* assume all lowpoly tessfaces can be quads */ + /* Assume all low-poly tessfaces can be quads. */ tris_high = MEM_callocN(sizeof(TriTessFace *) * tot_highpoly, "MVerts Highpoly Mesh Array"); - /* assume all highpoly tessfaces are triangles */ + /* Assume all high-poly tessfaces are triangles. */ me_highpoly = MEM_mallocN(sizeof(Mesh *) * tot_highpoly, "Highpoly Derived Meshes"); treeData = MEM_callocN(sizeof(BVHTreeFromMesh) * tot_highpoly, "Highpoly BVH Trees"); @@ -583,7 +583,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, BKE_mesh_runtime_looptri_ensure(me_highpoly[i]); if (me_highpoly[i]->runtime.looptris.len != 0) { - /* Create a BVH-tree for each highpoly object. */ + /* Create a BVH-tree for each `highpoly` object. */ BKE_bvhtree_from_mesh_get(&treeData[i], me_highpoly[i], BVHTREE_FROM_LOOPTRI, 2); if (treeData[i].tree == NULL) { diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c index 86ed88d37ab..657cd1f606b 100644 --- a/source/blender/render/intern/engine.c +++ b/source/blender/render/intern/engine.c @@ -679,7 +679,7 @@ static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer) DRW_render_context_enable(engine->re); } - DEG_evaluate_on_framechange(depsgraph, CFRA); + DEG_evaluate_on_framechange(depsgraph, BKE_scene_frame_get(scene)); if (use_gpu_context) { DRW_render_context_disable(engine->re); diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c index bc03158f036..6329901b4ce 100644 --- a/source/blender/render/intern/pipeline.c +++ b/source/blender/render/intern/pipeline.c @@ -1828,7 +1828,7 @@ void RE_SetReports(Render *re, ReportList *reports) static void render_update_depsgraph(Render *re) { Scene *scene = re->scene; - DEG_evaluate_on_framechange(re->pipeline_depsgraph, CFRA); + DEG_evaluate_on_framechange(re->pipeline_depsgraph, BKE_scene_frame_get(scene)); BKE_scene_update_sound(re->pipeline_depsgraph, re->main); } @@ -2410,7 +2410,7 @@ void RE_RenderAnim(Render *re, * -sergey- */ { - float ctime = BKE_scene_frame_get(scene); + float ctime = BKE_scene_ctime_get(scene); AnimData *adt = BKE_animdata_from_id(&scene->id); const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( re->pipeline_depsgraph, ctime); diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index d883234dc15..31d5bf67f28 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -169,7 +169,7 @@ static void pointdensity_cache_psys( ParticleCacheKey *cache; ParticleSimulationData sim = {NULL}; ParticleData *pa = NULL; - float cfra = BKE_scene_frame_get(scene); + float cfra = BKE_scene_ctime_get(scene); int i /*, Childexists*/ /* UNUSED */; int total_particles; int data_used; @@ -782,7 +782,7 @@ static void particle_system_minmax(Depsgraph *depsgraph, float max[3]) { const float size[3] = {radius, radius, radius}; - const float cfra = BKE_scene_frame_get(scene); + const float cfra = BKE_scene_ctime_get(scene); ParticleSettings *part = psys->part; ParticleSimulationData sim = {NULL}; ParticleData *pa = NULL; diff --git a/source/blender/sequencer/CMakeLists.txt b/source/blender/sequencer/CMakeLists.txt index 9340cfbf03d..e324bc8b407 100644 --- a/source/blender/sequencer/CMakeLists.txt +++ b/source/blender/sequencer/CMakeLists.txt @@ -77,9 +77,9 @@ set(SRC intern/proxy_job.c intern/render.c intern/render.h + intern/sequence_lookup.c intern/sequencer.c intern/sequencer.h - intern/sequence_lookup.c intern/sound.c intern/strip_add.c intern/strip_edit.c diff --git a/source/blender/sequencer/SEQ_clipboard.h b/source/blender/sequencer/SEQ_clipboard.h index 4b2bf69a8ac..ea7f01e6ae3 100644 --- a/source/blender/sequencer/SEQ_clipboard.h +++ b/source/blender/sequencer/SEQ_clipboard.h @@ -29,12 +29,16 @@ extern "C" { struct ListBase; struct Main; +struct Scene; +struct Sequence; extern struct ListBase seqbase_clipboard; extern int seqbase_clipboard_frame; void SEQ_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase); void SEQ_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); void SEQ_clipboard_free(void); +void SEQ_clipboard_active_seq_name_store(struct Scene *scene); +bool SEQ_clipboard_pasted_seq_was_active(struct Sequence *pasted_seq); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/clipboard.c b/source/blender/sequencer/intern/clipboard.c index e3f82dd4bb0..9e702a4e60b 100644 --- a/source/blender/sequencer/intern/clipboard.c +++ b/source/blender/sequencer/intern/clipboard.c @@ -24,6 +24,8 @@ * \ingroup bke */ +#include <string.h> + #include "MEM_guardedalloc.h" #include "DNA_scene_types.h" @@ -31,6 +33,7 @@ #include "DNA_sound_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BKE_main.h" #include "BKE_movieclip.h" @@ -38,6 +41,7 @@ #include "BKE_sound.h" #include "SEQ_clipboard.h" +#include "SEQ_select.h" #include "sequencer.h" @@ -55,6 +59,7 @@ ListBase seqbase_clipboard; int seqbase_clipboard_frame; +static char seq_clipboard_active_seq_name[SEQ_NAME_MAXSTR]; void seq_clipboard_pointers_free(struct ListBase *seqbase); @@ -177,3 +182,26 @@ void SEQ_clipboard_pointers_restore(ListBase *seqbase, Main *bmain) SEQ_clipboard_pointers_restore(&seq->seqbase, bmain); } } + +void SEQ_clipboard_active_seq_name_store(Scene *scene) +{ + Sequence *active_seq = SEQ_select_active_get(scene); + if (active_seq != NULL) { + STRNCPY(seq_clipboard_active_seq_name, active_seq->name); + } + else { + seq_clipboard_active_seq_name[0] = '\0'; + } +} + +/** + * Check if strip was active when it was copied. User should restrict this check to pasted strips + * before ensuring original name, because strip name comparison is used to check. + * + * \param pasted_seq: Strip that is pasted(duplicated) from clipboard + * \return true if strip was active, false otherwise + */ +bool SEQ_clipboard_pasted_seq_was_active(Sequence *pasted_seq) +{ + return STREQ(pasted_seq->name, seq_clipboard_active_seq_name); +} diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 39ccc5a53e5..1f4598d33fe 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -31,6 +31,7 @@ /* dna-savable wmStructs here */ #include "BLI_compiler_attrs.h" +#include "BLI_sys_types.h" #include "DNA_windowmanager_types.h" #include "WM_keymap.h" @@ -1015,7 +1016,7 @@ bool WM_xr_action_state_get(const wmXrData *xr, bool WM_xr_haptic_action_apply(wmXrData *xr, const char *action_set_name, const char *action_name, - const long long *duration, + const int64_t *duration, const float *frequency, const float *amplitude); void WM_xr_haptic_action_stop(wmXrData *xr, const char *action_set_name, const char *action_name); diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 3b78327872d..93b8495b309 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -124,14 +124,14 @@ static void window_set_custom_cursor( wmWindow *win, const uchar mask[16][2], const uchar bitmap[16][2], int hotx, int hoty) { GHOST_SetCustomCursorShape( - win->ghostwin, (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotx, hoty, true); + win->ghostwin, (uint8_t *)bitmap, (uint8_t *)mask, 16, 16, hotx, hoty, true); } static void window_set_custom_cursor_ex(wmWindow *win, BCursor *cursor) { GHOST_SetCustomCursorShape(win->ghostwin, - (GHOST_TUns8 *)cursor->bitmap, - (GHOST_TUns8 *)cursor->mask, + (uint8_t *)cursor->bitmap, + (uint8_t *)cursor->mask, 16, 16, cursor->hotx, diff --git a/source/blender/windowmanager/intern/wm_event_query.c b/source/blender/windowmanager/intern/wm_event_query.c index 905b0f7b128..e7603a02cff 100644 --- a/source/blender/windowmanager/intern/wm_event_query.c +++ b/source/blender/windowmanager/intern/wm_event_query.c @@ -484,7 +484,10 @@ int WM_event_absolute_delta_y(const struct wmEvent *event) * \{ */ #ifdef WITH_INPUT_IME -/* most os using ctrl/oskey + space to switch ime, avoid added space */ +/** + * Most OS's use `Ctrl+Space` / `OsKey+Space` to switch IME, + * so don't type in the space character. + */ bool WM_event_is_ime_switch(const struct wmEvent *event) { return event->val == KM_PRESS && event->type == EVT_SPACEKEY && diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 1f081d3b02e..fa21dbcb4bb 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -1357,7 +1357,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey) { GHOST_GLSettings glsettings = {0}; - GHOST_TUns32 scr_w, scr_h; + uint32_t scr_w, scr_h; GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &scr_w, &scr_h); @@ -1405,7 +1405,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) { struct ImBuf *ibuf = NULL; static char filepath[FILE_MAX]; /* abused to return dropped file path */ - GHOST_TUns32 maxwinx, maxwiny; + uint32_t maxwinx, maxwiny; int i; /* This was done to disambiguate the name for use under c++. */ int start_x = 0, start_y = 0; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 954976fddb6..1b08b8dad92 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -462,7 +462,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) /* Informs GHOST of unsaved changes, to set window modified visual indicator (macOS) * and to give hint of unsaved changes for a user warning mechanism in case of OS application * terminate request (e.g. OS Shortcut Alt+F4, Command+Q, (...), or session end). */ - GHOST_SetWindowModifiedState(win->ghostwin, (GHOST_TUns8)!wm->file_saved); + GHOST_SetWindowModifiedState(win->ghostwin, (bool)!wm->file_saved); } } @@ -1722,7 +1722,7 @@ static char *wm_clipboard_text_get_ex(bool selection, int *r_len, bool firstline return NULL; } - char *buf = (char *)GHOST_getClipboard(selection); + char *buf = GHOST_getClipboard(selection); if (!buf) { *r_len = 0; return NULL; @@ -1809,10 +1809,10 @@ void WM_clipboard_text_set(const char *buf, bool selection) } *p2 = '\0'; - GHOST_putClipboard((GHOST_TInt8 *)newbuf, selection); + GHOST_putClipboard(newbuf, selection); MEM_freeN(newbuf); #else - GHOST_putClipboard((GHOST_TInt8 *)buf, selection); + GHOST_putClipboard(buf, selection); #endif } } diff --git a/source/blender/windowmanager/xr/intern/wm_xr_actions.c b/source/blender/windowmanager/xr/intern/wm_xr_actions.c index 51ed3dcfd3c..7eabd29baa0 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_actions.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_actions.c @@ -462,7 +462,7 @@ bool WM_xr_action_state_get(const wmXrData *xr, bool WM_xr_haptic_action_apply(wmXrData *xr, const char *action_set_name, const char *action_name, - const long long *duration, + const int64_t *duration, const float *frequency, const float *amplitude) { diff --git a/tests/performance/api/__init__.py b/tests/performance/api/__init__.py index 6f344a41841..2dc9283c44a 100644 --- a/tests/performance/api/__init__.py +++ b/tests/performance/api/__init__.py @@ -5,4 +5,3 @@ from .device import TestDevice, TestMachine from .config import TestEntry, TestQueue, TestConfig from .test import Test, TestCollection from .graph import TestGraph - diff --git a/tests/performance/api/config.py b/tests/performance/api/config.py index 900cac0a0bb..68f4df8d487 100644 --- a/tests/performance/api/config.py +++ b/tests/performance/api/config.py @@ -10,12 +10,14 @@ from typing import Dict, List from .test import TestCollection + def get_build_hash(args: None) -> str: import bpy import sys build_hash = bpy.app.build_hash.decode('utf-8') return '' if build_hash == 'Unknown' else build_hash + @dataclass class TestEntry: """Test to run, a combination of revision, test and device.""" @@ -42,6 +44,7 @@ class TestEntry: for field in self.__dataclass_fields__: setattr(self, field, json_dict[field]) + class TestQueue: """Queue of tests to be run or inspected. Matches JSON file on disk.""" @@ -99,6 +102,7 @@ class TestQueue: with open(self.filepath, 'w') as f: json.dump(json_entries, f, indent=2) + class TestConfig: """Test configuration, containing a subset of revisions, tests and devices.""" diff --git a/tests/performance/api/device.py b/tests/performance/api/device.py index e27540da747..b61ae42be36 100644 --- a/tests/performance/api/device.py +++ b/tests/performance/api/device.py @@ -4,6 +4,7 @@ import platform import subprocess from typing import List + def get_cpu_name() -> str: # Get full CPU name. if platform.system() == "Windows": @@ -19,6 +20,7 @@ def get_cpu_name() -> str: return "Unknown CPU" + def get_gpu_device(args: None) -> List: # Get the list of available Cycles GPU devices. import bpy @@ -41,6 +43,7 @@ def get_gpu_device(args: None) -> List: return result + class TestDevice: def __init__(self, device_type: str, device_id: str, name: str, operating_system: str): self.type = device_type @@ -48,6 +51,7 @@ class TestDevice: self.name = name self.operating_system = operating_system + class TestMachine: def __init__(self, env, need_gpus: bool): operating_system = platform.system() @@ -65,4 +69,3 @@ class TestMachine: def cpu_device(self) -> TestDevice: return self.devices[0] - diff --git a/tests/performance/api/environment.py b/tests/performance/api/environment.py index 7c4e5e761a6..c9ddd493394 100644 --- a/tests/performance/api/environment.py +++ b/tests/performance/api/environment.py @@ -15,6 +15,7 @@ from typing import Callable, Dict, List from .config import TestConfig from .device import TestMachine + class TestEnvironment: def __init__(self, blender_git_dir: pathlib.Path, base_dir: pathlib.Path): self.blender_git_dir = blender_git_dir diff --git a/tests/performance/api/graph.py b/tests/performance/api/graph.py index e2d2e7d2058..eb411915ad9 100644 --- a/tests/performance/api/graph.py +++ b/tests/performance/api/graph.py @@ -6,6 +6,7 @@ import json import pathlib from typing import Dict, List + class TestGraph: def __init__(self, json_filepaths: List[pathlib.Path]): # Initialize graph from JSON file. Note that this is implemented without @@ -102,4 +103,3 @@ class TestGraph: contents = template.replace('%JSON_DATA%', self.json) with open(filepath, "w") as f: f.write(contents) - diff --git a/tests/performance/api/test.py b/tests/performance/api/test.py index 23459b4b421..7e8193d2c21 100644 --- a/tests/performance/api/test.py +++ b/tests/performance/api/test.py @@ -4,6 +4,7 @@ import abc import fnmatch from typing import Dict, List + class Test: @abc.abstractmethod def name(self) -> str: @@ -29,6 +30,7 @@ class Test: Execute the test and report results. """ + class TestCollection: def __init__(self, env, names_filter: List=['*'], categories_filter: List=['*']): import importlib diff --git a/tests/performance/tests/__init__.py b/tests/performance/tests/__init__.py index 69b72d23c3f..ac3e613174f 100644 --- a/tests/performance/tests/__init__.py +++ b/tests/performance/tests/__init__.py @@ -1,2 +1 @@ # Apache License, Version 2.0 - diff --git a/tests/performance/tests/animation.py b/tests/performance/tests/animation.py index de3b8817820..1a92f1a9718 100644 --- a/tests/performance/tests/animation.py +++ b/tests/performance/tests/animation.py @@ -3,6 +3,7 @@ import api import os + def _run(args): import bpy import time @@ -18,6 +19,7 @@ def _run(args): result = {'time': elapsed_time} return result + class AnimationTest(api.Test): def __init__(self, filepath): self.filepath = filepath @@ -33,6 +35,7 @@ class AnimationTest(api.Test): result, _ = env.run_in_blender(_run, args) return result + def generate(env): filepaths = env.find_blend_files('animation') return [AnimationTest(filepath) for filepath in filepaths] diff --git a/tests/performance/tests/blend_load.py b/tests/performance/tests/blend_load.py index 4df8bd774d3..5fe498fd3d7 100644 --- a/tests/performance/tests/blend_load.py +++ b/tests/performance/tests/blend_load.py @@ -4,6 +4,7 @@ import api import os import pathlib + def _run(filepath): import bpy import time @@ -20,6 +21,7 @@ def _run(filepath): result = {'time': elapsed_time} return result + class BlendLoadTest(api.Test): def __init__(self, filepath): self.filepath = filepath @@ -34,6 +36,7 @@ class BlendLoadTest(api.Test): result, _ = env.run_in_blender(_run, str(self.filepath)) return result + def generate(env): filepaths = env.find_blend_files('*/*') return [BlendLoadTest(filepath) for filepath in filepaths] diff --git a/tests/performance/tests/cycles.py b/tests/performance/tests/cycles.py index 185d4e8e6c0..f79e7333458 100644 --- a/tests/performance/tests/cycles.py +++ b/tests/performance/tests/cycles.py @@ -3,6 +3,7 @@ import api import os + def _run(args): import bpy import time @@ -39,6 +40,7 @@ def _run(args): return None + class CyclesTest(api.Test): def __init__(self, filepath): self.filepath = filepath @@ -74,6 +76,7 @@ class CyclesTest(api.Test): raise Exception("Error parsing render time output") + def generate(env): filepaths = env.find_blend_files('cycles-x/*') return [CyclesTest(filepath) for filepath in filepaths] diff --git a/tests/python/alembic_export_tests.py b/tests/python/alembic_export_tests.py index 9d1738691f0..23a4a376533 100644 --- a/tests/python/alembic_export_tests.py +++ b/tests/python/alembic_export_tests.py @@ -197,7 +197,7 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest): def test_hierarchical_export(self, tempdir: pathlib.Path): abc = tempdir / 'cubes_hierarchical.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_objects_only=True, flatten=False)" % abc.as_posix() + "visible_objects_only=True, flatten=False)" % abc.as_posix() self.run_blender('cubes-hierarchy.blend', script) # Now check the resulting Alembic file. @@ -215,7 +215,7 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest): def test_flat_export(self, tempdir: pathlib.Path): abc = tempdir / 'cubes_flat.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_objects_only=True, flatten=True)" % abc.as_posix() + "visible_objects_only=True, flatten=True)" % abc.as_posix() self.run_blender('cubes-hierarchy.blend', script) # Now check the resulting Alembic file. @@ -236,7 +236,7 @@ class DupliGroupExportTest(AbstractAlembicTest): def test_hierarchical_export(self, tempdir: pathlib.Path): abc = tempdir / 'dupligroup_hierarchical.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_objects_only=True, flatten=False)" % abc.as_posix() + "visible_objects_only=True, flatten=False)" % abc.as_posix() self.run_blender('dupligroup-scene.blend', script) # Now check the resulting Alembic file. @@ -254,7 +254,7 @@ class DupliGroupExportTest(AbstractAlembicTest): def test_flat_export(self, tempdir: pathlib.Path): abc = tempdir / 'dupligroup_hierarchical.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_objects_only=True, flatten=True)" % abc.as_posix() + "visible_objects_only=True, flatten=True)" % abc.as_posix() self.run_blender('dupligroup-scene.blend', script) # Now check the resulting Alembic file. @@ -332,7 +332,7 @@ class CurveExportTest(AbstractAlembicTest): def test_export_single_curve(self, tempdir: pathlib.Path): abc = tempdir / 'single-curve.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_objects_only=True, flatten=False)" % abc.as_posix() + "visible_objects_only=True, flatten=False)" % abc.as_posix() self.run_blender('single-curve.blend', script) # Now check the resulting Alembic file. @@ -353,7 +353,7 @@ class HairParticlesExportTest(AbstractAlembicTest): def _do_test(self, tempdir: pathlib.Path, export_hair: bool, export_particles: bool) -> pathlib.Path: abc = tempdir / 'hair-particles.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_objects_only=True, flatten=False, " \ + "visible_objects_only=True, flatten=False, " \ "export_hair=%r, export_particles=%r, as_background_job=False)" \ % (abc.as_posix(), export_hair, export_particles) self.run_blender('hair-particles.blend', script) @@ -419,7 +419,7 @@ class UVMapExportTest(AbstractAlembicTest): basename = 'T77021-multiple-uvmaps-animated-mesh' abc = tempdir / f'{basename}.abc' script = f"import bpy; bpy.ops.wm.alembic_export(filepath='{abc.as_posix()}', start=1, end=1, " \ - f"renderable_only=True, visible_objects_only=True, flatten=False)" + f"visible_objects_only=True, flatten=False)" self.run_blender(f'{basename}.blend', script) self.maxDiff = 1000 @@ -468,7 +468,7 @@ class LongNamesExportTest(AbstractAlembicTest): def test_export_long_names(self, tempdir: pathlib.Path): abc = tempdir / 'long-names.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=False, visible_objects_only=False, flatten=False)" % abc.as_posix() + "visible_objects_only=False, flatten=False)" % abc.as_posix() self.run_blender('long-names.blend', script) name_parts = [ @@ -565,7 +565,7 @@ class InvisibleObjectExportTest(AbstractAlembicTest): def test_hierarchical_export(self, tempdir: pathlib.Path): abc = tempdir / 'visibility.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=2, " \ - "renderable_only=False, visible_objects_only=False)" % abc.as_posix() + "visible_objects_only=False)" % abc.as_posix() self.run_blender('visibility.blend', script) def test(cube_name: str, expect_visible: bool): diff --git a/tests/python/bl_alembic_io_test.py b/tests/python/bl_alembic_io_test.py index 53a0879f160..c0d0bcdea70 100644 --- a/tests/python/bl_alembic_io_test.py +++ b/tests/python/bl_alembic_io_test.py @@ -300,7 +300,6 @@ class CameraExportImportTest(unittest.TestCase): abc_path = self.tempdir / "camera_transforms.abc" self.assertIn('FINISHED', bpy.ops.wm.alembic_export( filepath=str(abc_path), - renderable_only=False, flatten=flatten, )) diff --git a/tests/python/bl_animation_fcurves.py b/tests/python/bl_animation_fcurves.py index 2ec04749d70..9017c1ee037 100644 --- a/tests/python/bl_animation_fcurves.py +++ b/tests/python/bl_animation_fcurves.py @@ -40,6 +40,7 @@ class AbstractAnimationTest: self.assertTrue(self.testdir.exists(), 'Test dir %s should exist' % self.testdir) + class FCurveEvaluationTest(AbstractAnimationTest, unittest.TestCase): def test_fcurve_versioning_291(self): # See D8752. diff --git a/tests/python/bl_blendfile_library_overrides.py b/tests/python/bl_blendfile_library_overrides.py index 48625a1ecdb..c9c89c01cee 100644 --- a/tests/python/bl_blendfile_library_overrides.py +++ b/tests/python/bl_blendfile_library_overrides.py @@ -69,7 +69,7 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase): assert(len(local_id.override_library.properties) == 1) override_prop = local_id.override_library.properties[0] - assert(override_prop.rna_path == "location"); + assert(override_prop.rna_path == "location") assert(len(override_prop.operations) == 1) override_operation = override_prop.operations[0] assert(override_operation.operation == 'REPLACE') @@ -96,7 +96,7 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase): self.assertIsNone(local_id.data.override_library) assert(len(local_id.override_library.properties) == 1) override_prop = local_id.override_library.properties[0] - assert(override_prop.rna_path == "scale"); + assert(override_prop.rna_path == "scale") assert(len(override_prop.operations) == 1) override_operation = override_prop.operations[0] assert(override_operation.operation == 'NOOP') @@ -116,14 +116,14 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase): assert(len(local_id.override_library.properties) == 2) override_prop = local_id.override_library.properties[0] - assert(override_prop.rna_path == "scale"); + assert(override_prop.rna_path == "scale") assert(len(override_prop.operations) == 1) override_operation = override_prop.operations[0] assert(override_operation.operation == 'NOOP') assert(override_operation.subitem_local_index == -1) override_prop = local_id.override_library.properties[1] - assert(override_prop.rna_path == "location"); + assert(override_prop.rna_path == "location") assert(len(override_prop.operations) == 1) override_operation = override_prop.operations[0] assert(override_operation.operation == 'REPLACE') diff --git a/tests/python/bl_pyapi_idprop.py b/tests/python/bl_pyapi_idprop.py index 1e570bf9a7f..38cd9d04a6b 100644 --- a/tests/python/bl_pyapi_idprop.py +++ b/tests/python/bl_pyapi_idprop.py @@ -140,6 +140,7 @@ class TestIdPropertyCreation(TestHelper, unittest.TestCase): with self.assertRaises(TypeError): self.id["a"] = self + class TestIdPropertyGroupView(TestHelper, unittest.TestCase): def test_type(self): diff --git a/tests/python/bl_run_operators_event_simulate.py b/tests/python/bl_run_operators_event_simulate.py index 92315d3e853..1cc621b9684 100644 --- a/tests/python/bl_run_operators_event_simulate.py +++ b/tests/python/bl_run_operators_event_simulate.py @@ -165,6 +165,16 @@ def gen_events_type_text(text): yield dict(type=type, value='RELEASE', **kw_extra) +def repr_action(name, args, kwargs): + return "%s(%s)" % ( + name, + ", ".join( + [repr(value) for value in args] + + [("%s=%r" % (key, value)) for key, value in kwargs.items()] + ) + ) + + # ----------------------------------------------------------------------------- # Simulate Events @@ -505,6 +515,18 @@ def argparse_create(): required=False, ) + parser.add_argument( + "--time-actions", + dest="time_actions", + default=False, + action="store_true", + help=( + "Display the time each action takes\n" + "(useful for measuring delay between key-presses)." + ), + required=False, + ) + # Collect doc-strings from static methods in `actions`. actions_docstring = [] for action_key in ACTION_DIR: @@ -554,7 +576,7 @@ def setup_default_preferences(prefs): # Main Function -def main_event_iter(*, action_list): +def main_event_iter(*, action_list, time_actions): """ Yield all events from action handlers. """ @@ -565,9 +587,18 @@ def main_event_iter(*, action_list): yield dict(type='MOUSEMOVE', value='NOTHING', x=x_init, y=y_init) + if time_actions: + import time + t_prev = time.time() + for (op, args, kwargs) in action_list: yield from handle_action(op, args, kwargs) + if time_actions: + t = time.time() + print("%.4f: %s" % ((t - t_prev), repr_action(op, args, kwargs))) + t_prev = t + def main(): from sys import argv @@ -588,7 +619,7 @@ def main(): bpy.app.use_event_simulate = False run_event_simulate( - event_iter=main_event_iter(action_list=args.actions), + event_iter=main_event_iter(action_list=args.actions, time_actions=args.time_actions), exit_fn=exit_fn, ) diff --git a/tests/python/compositor_render_tests.py b/tests/python/compositor_render_tests.py index 057d4a2e6dd..199e1c13b8e 100644 --- a/tests/python/compositor_render_tests.py +++ b/tests/python/compositor_render_tests.py @@ -16,6 +16,7 @@ try: except ImportError: inside_blender = False + def get_arguments(filepath, output_filepath): return [ "--background", diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py index 36c3f7d9fe5..ca0bc9f18b9 100644 --- a/tests/python/cycles_render_tests.py +++ b/tests/python/cycles_render_tests.py @@ -57,6 +57,7 @@ BLACKLIST_GPU = [ 'transparent_shadow_hair.*.blend', ] + def get_arguments(filepath, output_filepath): dirname = os.path.dirname(filepath) basedir = os.path.dirname(dirname) diff --git a/tests/python/modules/mesh_test.py b/tests/python/modules/mesh_test.py index 1749e798a32..6d921959e6f 100644 --- a/tests/python/modules/mesh_test.py +++ b/tests/python/modules/mesh_test.py @@ -680,7 +680,7 @@ class RunTest: test_name = each_test.test_name if self.verbose: print() - print("Running test {}/{}: {}...".format(test_number+1, len(self.tests), test_name)) + print("Running test {}/{}: {}...".format(test_number + 1, len(self.tests), test_name)) success = self.run_test(test_name) if not success: diff --git a/tests/python/modules/render_report.py b/tests/python/modules/render_report.py index c1ae0b05fcd..560f8e33585 100755 --- a/tests/python/modules/render_report.py +++ b/tests/python/modules/render_report.py @@ -287,7 +287,7 @@ class Report: -moz-background-size:50px 50px; background-size:50px 50px; - -webkit-background-size:50px 51px; /* override value for shitty webkit */ + -webkit-background-size:50px 51px; /* Override value for silly webkit. */ background-position:0 0, 25px 0, 25px -25px, 0px 25px; }} diff --git a/tests/python/operators.py b/tests/python/operators.py index c209b01c20c..4501df82175 100644 --- a/tests/python/operators.py +++ b/tests/python/operators.py @@ -321,7 +321,7 @@ def main(): MeshTest("CubeEdgeUnsubdivide", "testCubeEdgeUnsubdivide", "expectedCubeEdgeUnsubdivide", [OperatorSpecEditMode("unsubdivide", {}, "EDGE", {i for i in range(6)})]), MeshTest("UVSphereUnsubdivide", "testUVSphereUnsubdivide", "expectedUVSphereUnsubdivide", - [OperatorSpecEditMode("unsubdivide", {'iterations': 9}, "FACE", {i for i in range(512)})]), + [OperatorSpecEditMode("unsubdivide", {'iterations': 9}, "FACE", {i for i in range(512)})]), # vert connect path # Tip: It works only if there is an already existing face or more than 2 vertices. |