diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 255d487649b..6a084dcca22 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -88,103 +88,55 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_fpGetPointerInfoHistory(NULL), m_fpGetPointerPenInfoHistory(NULL), m_fpGetPointerTouchInfoHistory(NULL), - m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : NULL), + m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP), m_debug_context(is_debug) { - // Create window - if (state != GHOST_kWindowStateFullScreen) { - RECT rect; - MONITORINFO monitor; - GHOST_TUns32 tw, th; - -#ifndef _MSC_VER - int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME); - int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME); -#else - // MSVC 2012+ returns bogus values from GetSystemMetrics, bug in Windows - // http://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values - RECT cxrect = {0, 0, 0, 0}; - AdjustWindowRectEx( - &cxrect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0); - - int cxsizeframe = abs(cxrect.bottom); - int cysizeframe = abs(cxrect.left); -#endif - - width += cxsizeframe * 2; - height += cysizeframe * 2 + GetSystemMetrics(SM_CYCAPTION); - - rect.left = left; - rect.right = left + width; - rect.top = top; - rect.bottom = top + height; - - monitor.cbSize = sizeof(monitor); - monitor.dwFlags = 0; - - // take taskbar into account - GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor); - - th = monitor.rcWork.bottom - monitor.rcWork.top; - tw = monitor.rcWork.right - monitor.rcWork.left; - - if (tw < width) { - width = tw; - left = monitor.rcWork.left; - } - else if (monitor.rcWork.right < left + (int)width) - left = monitor.rcWork.right - width; - else if (left < monitor.rcWork.left) - left = monitor.rcWork.left; - - if (th < height) { - height = th; - top = monitor.rcWork.top; - } - else if (monitor.rcWork.bottom < top + (int)height) - top = monitor.rcWork.bottom - height; - else if (top < monitor.rcWork.top) - top = monitor.rcWork.top; - - int wintype = WS_OVERLAPPEDWINDOW; - if ((m_parentWindowHwnd != 0) && !dialog) { - wintype = WS_CHILD; - GetWindowRect(m_parentWindowHwnd, &rect); - left = 0; - top = 0; - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } - - wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0); - m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name - title_16, // pointer to window name - wintype, // window style - left, // horizontal position of window - top, // vertical position of window - width, // window width - height, // window height - dialog ? 0 : m_parentWindowHwnd, // handle to parent or owner window - 0, // handle to menu or child-window identifier - ::GetModuleHandle(0), // handle to application instance - 0); // pointer to window-creation data - free(title_16); + wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0); + RECT win_rect = {left, top, left + width, top + height}; + RECT parent_rect = {0, 0, 0, 0}; + if (parentwindow) { + GetWindowRect(m_parentWindowHwnd, &parent_rect); } - else { - wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0); - m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name + + DWORD style = parentwindow ? + WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX : + WS_OVERLAPPEDWINDOW; + + if (state == GHOST_kWindowStateFullScreen) { + style |= WS_MAXIMIZE; + } + + /* Forces owned windows onto taskbar and allows minimization. */ + DWORD extended_style = parentwindow ? WS_EX_APPWINDOW : 0; + + /* Monitor details. */ + MONITORINFOEX monitor; + monitor.cbSize = sizeof(MONITORINFOEX); + monitor.dwFlags = 0; + GetMonitorInfo( + MonitorFromRect(parentwindow ? &parent_rect : &win_rect, MONITOR_DEFAULTTONEAREST), + &monitor); + + /* Adjust our requested size to allow for caption and borders and constrain to monitor. */ + AdjustWindowRectEx(&win_rect, WS_CAPTION, FALSE, 0); + width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect.right - win_rect.left); + left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width); + height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect.bottom - win_rect.top); + top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height); + + m_hWnd = ::CreateWindowExW(extended_style, // window extended style + s_windowClassName, // pointer to registered class name title_16, // pointer to window name - WS_MAXIMIZE, // window style + style, // window style left, // horizontal position of window top, // vertical position of window width, // window width height, // window height - HWND_DESKTOP, // handle to parent or owner window + m_parentWindowHwnd, // handle to parent or owner window 0, // handle to menu or child-window identifier ::GetModuleHandle(0), // handle to application instance 0); // pointer to window-creation data - free(title_16); - } + free(title_16); m_user32 = ::LoadLibrary("user32.dll"); @@ -268,14 +220,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, } } - if (dialog && parentwindow) { - ::SetWindowLongPtr( - m_hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_SIZEBOX); - ::SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)m_parentWindowHwnd); - ::SetWindowPos( - m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - } - else if (parentwindow) { + if (parentwindow && !dialog) { RAWINPUTDEVICE device = {0}; device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/ device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ diff --git a/release/datafiles/locale b/release/datafiles/locale index 877a343fed9..6c693b5b0b2 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 877a343fed9613d8e02e7fe7181d3bbb628506f2 +Subproject commit 6c693b5b0b27468d4fd2d2c47ea023eebbb0dbc0 diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index 2265e70df39..6383d7dfcca 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -105,7 +105,7 @@ const UserDef U_default = { .autoexec_paths = {NULL}, .user_menus = {NULL}, - .keyconfigstr = "blender", + .keyconfigstr = "Blender", .undosteps = 32, .undomemory = 0, .gp_manhattandist = 1, diff --git a/release/scripts/addons b/release/scripts/addons index a3fa40ec0ba..dfeb905d62a 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit a3fa40ec0ba525bc96cbfad49f854a0230b0524e +Subproject commit dfeb905d62ae6d759d8da930f291e73505e6ca67 diff --git a/release/scripts/modules/bl_keymap_utils/platform_helpers.py b/release/scripts/modules/bl_keymap_utils/platform_helpers.py index e18a902c562..a6058b993d5 100644 --- a/release/scripts/modules/bl_keymap_utils/platform_helpers.py +++ b/release/scripts/modules/bl_keymap_utils/platform_helpers.py @@ -49,6 +49,7 @@ def keyconfig_data_oskey_from_ctrl_for_macos(keyconfig_data_src): 'W', 'ACCENT_GRAVE', 'PERIOD', + 'TAB', }): if (not item_event.get("alt")) and (not item_event.get("shift")): return False diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index 3860445233d..fad52eae84a 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -201,12 +201,13 @@ _display_name_literals = { } -def display_name(name, *, has_ext=True): +def display_name(name, *, has_ext=True, title_case=True): """ Creates a display string from name to be used menus and the user interface. - Capitalize the first letter in all lowercase names, - mixed case names are kept as is. Intended for use with - filenames and module names. + Intended for use with filenames and module names. + + :arg has_ext: Remove file extension from name + :arg title_case: Convert lowercase names to title case """ if has_ext: @@ -220,7 +221,7 @@ def display_name(name, *, has_ext=True): # (when paths can't start with numbers for eg). name = name.replace("_", " ").lstrip(" ") - if name.islower(): + if title_case and name.islower(): name = name.lower().title() name = _clean_utf8(name) diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index 897010e80cf..7f39cc5d422 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -606,7 +606,7 @@ def preset_find(name, preset_path, display_name=False, ext=".py"): if display_name: filename = "" for fn in _os.listdir(directory): - if fn.endswith(ext) and name == _bpy.path.display_name(fn): + if fn.endswith(ext) and name == _bpy.path.display_name(fn, title_case=False): filename = fn break else: @@ -624,7 +624,7 @@ def keyconfig_init(): active_config = _preferences.keymap.active_keyconfig # Load the default key configuration. - default_filepath = preset_find("blender", "keyconfig") + default_filepath = preset_find("Blender", "keyconfig") keyconfig_set(default_filepath) # Set the active key configuration if different diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index d863778a9c2..5d89763f34b 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -982,6 +982,7 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): props_default=props_default, filter_ext=lambda ext: ext.lower() in ext_valid, add_operator=add_operator, + display_name=lambda name: bpy.path.display_name(name, title_case=False) ) @classmethod diff --git a/release/scripts/presets/cloth/cotton.py b/release/scripts/presets/cloth/Cotton.py similarity index 100% rename from release/scripts/presets/cloth/cotton.py rename to release/scripts/presets/cloth/Cotton.py diff --git a/release/scripts/presets/cloth/denim.py b/release/scripts/presets/cloth/Denim.py similarity index 100% rename from release/scripts/presets/cloth/denim.py rename to release/scripts/presets/cloth/Denim.py diff --git a/release/scripts/presets/cloth/leather.py b/release/scripts/presets/cloth/Leather.py similarity index 100% rename from release/scripts/presets/cloth/leather.py rename to release/scripts/presets/cloth/Leather.py diff --git a/release/scripts/presets/cloth/rubber.py b/release/scripts/presets/cloth/Rubber.py similarity index 100% rename from release/scripts/presets/cloth/rubber.py rename to release/scripts/presets/cloth/Rubber.py diff --git a/release/scripts/presets/cloth/silk.py b/release/scripts/presets/cloth/Silk.py similarity index 100% rename from release/scripts/presets/cloth/silk.py rename to release/scripts/presets/cloth/Silk.py diff --git a/release/scripts/presets/cycles/integrator/direct_light.py b/release/scripts/presets/cycles/integrator/Direct_Light.py similarity index 100% rename from release/scripts/presets/cycles/integrator/direct_light.py rename to release/scripts/presets/cycles/integrator/Direct_Light.py diff --git a/release/scripts/presets/cycles/integrator/full_global_illumination.py b/release/scripts/presets/cycles/integrator/Full_Global_Illumination.py similarity index 100% rename from release/scripts/presets/cycles/integrator/full_global_illumination.py rename to release/scripts/presets/cycles/integrator/Full_Global_Illumination.py diff --git a/release/scripts/presets/cycles/integrator/limited_global_illumination.py b/release/scripts/presets/cycles/integrator/Limited_Global_Illumination.py similarity index 100% rename from release/scripts/presets/cycles/integrator/limited_global_illumination.py rename to release/scripts/presets/cycles/integrator/Limited_Global_Illumination.py diff --git a/release/scripts/presets/cycles/sampling/final.py b/release/scripts/presets/cycles/sampling/Final.py similarity index 100% rename from release/scripts/presets/cycles/sampling/final.py rename to release/scripts/presets/cycles/sampling/Final.py diff --git a/release/scripts/presets/cycles/sampling/preview.py b/release/scripts/presets/cycles/sampling/Preview.py similarity index 100% rename from release/scripts/presets/cycles/sampling/preview.py rename to release/scripts/presets/cycles/sampling/Preview.py diff --git a/release/scripts/presets/ffmpeg/h264_in_MP4.py b/release/scripts/presets/ffmpeg/H264_in_MP4.py similarity index 100% rename from release/scripts/presets/ffmpeg/h264_in_MP4.py rename to release/scripts/presets/ffmpeg/H264_in_MP4.py diff --git a/release/scripts/presets/ffmpeg/h264_in_Matroska.py b/release/scripts/presets/ffmpeg/H264_in_Matroska.py similarity index 100% rename from release/scripts/presets/ffmpeg/h264_in_Matroska.py rename to release/scripts/presets/ffmpeg/H264_in_Matroska.py diff --git a/release/scripts/presets/ffmpeg/h264_in_Matroska_for_scrubbing.py b/release/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py similarity index 100% rename from release/scripts/presets/ffmpeg/h264_in_Matroska_for_scrubbing.py rename to release/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py diff --git a/release/scripts/presets/ffmpeg/ogg_theora.py b/release/scripts/presets/ffmpeg/Ogg_Theora.py similarity index 100% rename from release/scripts/presets/ffmpeg/ogg_theora.py rename to release/scripts/presets/ffmpeg/Ogg_Theora.py diff --git a/release/scripts/presets/ffmpeg/xvid.py b/release/scripts/presets/ffmpeg/Xvid.py similarity index 100% rename from release/scripts/presets/ffmpeg/xvid.py rename to release/scripts/presets/ffmpeg/Xvid.py diff --git a/release/scripts/presets/fluid/honey.py b/release/scripts/presets/fluid/Honey.py similarity index 100% rename from release/scripts/presets/fluid/honey.py rename to release/scripts/presets/fluid/Honey.py diff --git a/release/scripts/presets/fluid/oil.py b/release/scripts/presets/fluid/Oil.py similarity index 100% rename from release/scripts/presets/fluid/oil.py rename to release/scripts/presets/fluid/Oil.py diff --git a/release/scripts/presets/fluid/water.py b/release/scripts/presets/fluid/Water.py similarity index 100% rename from release/scripts/presets/fluid/water.py rename to release/scripts/presets/fluid/Water.py diff --git a/release/scripts/presets/gpencil_material/fill_only.py b/release/scripts/presets/gpencil_material/Fill_Only.py similarity index 100% rename from release/scripts/presets/gpencil_material/fill_only.py rename to release/scripts/presets/gpencil_material/Fill_Only.py diff --git a/release/scripts/presets/gpencil_material/stroke_only.py b/release/scripts/presets/gpencil_material/Stroke_Only.py similarity index 100% rename from release/scripts/presets/gpencil_material/stroke_only.py rename to release/scripts/presets/gpencil_material/Stroke_Only.py diff --git a/release/scripts/presets/gpencil_material/stroke_and_fill.py b/release/scripts/presets/gpencil_material/Stroke_and_Fill.py similarity index 100% rename from release/scripts/presets/gpencil_material/stroke_and_fill.py rename to release/scripts/presets/gpencil_material/Stroke_and_Fill.py diff --git a/release/scripts/presets/hair_dynamics/default.py b/release/scripts/presets/hair_dynamics/Default.py similarity index 100% rename from release/scripts/presets/hair_dynamics/default.py rename to release/scripts/presets/hair_dynamics/Default.py diff --git a/release/scripts/presets/interface_theme/blender_dark.xml b/release/scripts/presets/interface_theme/Blender_Dark.xml similarity index 100% rename from release/scripts/presets/interface_theme/blender_dark.xml rename to release/scripts/presets/interface_theme/Blender_Dark.xml diff --git a/release/scripts/presets/interface_theme/blender_light.xml b/release/scripts/presets/interface_theme/Blender_Light.xml similarity index 100% rename from release/scripts/presets/interface_theme/blender_light.xml rename to release/scripts/presets/interface_theme/Blender_Light.xml diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/Blender.py similarity index 100% rename from release/scripts/presets/keyconfig/blender.py rename to release/scripts/presets/keyconfig/Blender.py diff --git a/release/scripts/presets/keyconfig/blender_27x.py b/release/scripts/presets/keyconfig/Blender_27x.py similarity index 100% rename from release/scripts/presets/keyconfig/blender_27x.py rename to release/scripts/presets/keyconfig/Blender_27x.py diff --git a/release/scripts/presets/keyconfig/industry_compatible.py b/release/scripts/presets/keyconfig/Industry_Compatible.py similarity index 100% rename from release/scripts/presets/keyconfig/industry_compatible.py rename to release/scripts/presets/keyconfig/Industry_Compatible.py diff --git a/release/scripts/presets/render/4k_UHDTV_2160p.py b/release/scripts/presets/render/4K_UHDTV_2160p.py similarity index 100% rename from release/scripts/presets/render/4k_UHDTV_2160p.py rename to release/scripts/presets/render/4K_UHDTV_2160p.py diff --git a/release/scripts/presets/tracking_settings/blurry_footage.py b/release/scripts/presets/tracking_settings/Blurry_Footage.py similarity index 100% rename from release/scripts/presets/tracking_settings/blurry_footage.py rename to release/scripts/presets/tracking_settings/Blurry_Footage.py diff --git a/release/scripts/presets/tracking_settings/default.py b/release/scripts/presets/tracking_settings/Default.py similarity index 100% rename from release/scripts/presets/tracking_settings/default.py rename to release/scripts/presets/tracking_settings/Default.py diff --git a/release/scripts/presets/tracking_settings/fast_motion.py b/release/scripts/presets/tracking_settings/Fast_Motion.py similarity index 100% rename from release/scripts/presets/tracking_settings/fast_motion.py rename to release/scripts/presets/tracking_settings/Fast_Motion.py diff --git a/release/scripts/presets/tracking_settings/planar.py b/release/scripts/presets/tracking_settings/Planar.py similarity index 100% rename from release/scripts/presets/tracking_settings/planar.py rename to release/scripts/presets/tracking_settings/Planar.py diff --git a/release/scripts/presets/tracking_track_color/default.py b/release/scripts/presets/tracking_track_color/Default.py similarity index 100% rename from release/scripts/presets/tracking_track_color/default.py rename to release/scripts/presets/tracking_track_color/Default.py diff --git a/release/scripts/presets/tracking_track_color/far_plane.py b/release/scripts/presets/tracking_track_color/Far_Plane.py similarity index 100% rename from release/scripts/presets/tracking_track_color/far_plane.py rename to release/scripts/presets/tracking_track_color/Far_Plane.py diff --git a/release/scripts/presets/tracking_track_color/near_plane.py b/release/scripts/presets/tracking_track_color/Near_Plane.py similarity index 100% rename from release/scripts/presets/tracking_track_color/near_plane.py rename to release/scripts/presets/tracking_track_color/Near_Plane.py diff --git a/release/scripts/presets/tracking_track_color/object.py b/release/scripts/presets/tracking_track_color/Object.py similarity index 100% rename from release/scripts/presets/tracking_track_color/object.py rename to release/scripts/presets/tracking_track_color/Object.py diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 793a8648ee4..5132b358f5e 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -77,7 +77,7 @@ class AddPresetBase: setattr(cls, attr, trans) return trans - name = name.lower().strip() + name = name.strip() name = bpy.path.display_name_to_filepath(name) trans = maketrans_init() # Strip surrounding "_" as they are displayed as spaces. @@ -249,7 +249,7 @@ class ExecutePreset(Operator): # change the menu title to the most recently chosen option preset_class = getattr(bpy.types, self.menu_idname) - preset_class.bl_label = bpy.path.display_name(basename(filepath)) + preset_class.bl_label = bpy.path.display_name(basename(filepath), title_case=False) ext = splitext(filepath)[1].lower() diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index f04a3f6eaf6..f15eed64913 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -506,6 +506,7 @@ geometry_node_categories = [ NodeItem("FunctionNodeRandomFloat"), NodeItem("ShaderNodeValue"), NodeItem("FunctionNodeInputVector"), + NodeItem("GeometryNodeIsViewport"), ]), GeometryNodeCategory("GEO_MESH", "Mesh", items=[ NodeItem("GeometryNodeBoolean"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 17f116912fa..dcfd6ca7bdd 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1365,6 +1365,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE 1021 #define GEO_NODE_POINTS_TO_VOLUME 1022 #define GEO_NODE_COLLECTION_INFO 1023 +#define GEO_NODE_IS_VIEWPORT 1024 /** \} */ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index da874539232..923a77618aa 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1173,10 +1173,6 @@ static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot) static void nlaevalchan_free_data(NlaEvalChannel *nec) { nlavalidmask_free(&nec->domain); - - if (nec->blend_snapshot != NULL) { - nlaevalchan_snapshot_free(nec->blend_snapshot); - } } /* Initialize a full NLA evaluation state structure. */ @@ -1661,92 +1657,6 @@ static bool nla_combine_quaternion_get_inverted_strip_values(const float lower_v return true; } -/* Data about the current blend mode. */ -typedef struct NlaBlendData { - NlaEvalSnapshot *snapshot; - int mode; - float influence; - - NlaEvalChannel *blend_queue; -} NlaBlendData; - -/* Queue the channel for deferred blending. */ -static NlaEvalChannelSnapshot *nlaevalchan_queue_blend(NlaBlendData *blend, NlaEvalChannel *nec) -{ - if (!nec->in_blend) { - if (nec->blend_snapshot == NULL) { - nec->blend_snapshot = nlaevalchan_snapshot_new(nec); - } - - nec->in_blend = true; - nlaevalchan_snapshot_copy(nec->blend_snapshot, &nec->base_snapshot); - - nec->next_blend = blend->blend_queue; - blend->blend_queue = nec; - } - - return nec->blend_snapshot; -} - -/* Accumulate (i.e. blend) the given value on to the channel it affects. */ -static bool nlaeval_blend_value(NlaBlendData *blend, - NlaEvalChannel *nec, - int array_index, - float value) -{ - if (nec == NULL) { - return false; - } - - if (!nlaevalchan_validate_index_ex(nec, array_index)) { - return false; - } - - NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec); - float *p_value = &nec_snapshot->values[array_index]; - - if (blend->mode == NLASTRIP_MODE_COMBINE) { - /* Quaternion blending is deferred until all sub-channel values are known. */ - if (nec->mix_mode == NEC_MIX_QUATERNION) { - NlaEvalChannelSnapshot *blend_snapshot = nlaevalchan_queue_blend(blend, nec); - - blend_snapshot->values[array_index] = value; - } - else { - float base_value = nec->base_snapshot.values[array_index]; - - *p_value = nla_combine_value(nec->mix_mode, base_value, *p_value, value, blend->influence); - } - } - else { - *p_value = nla_blend_value(blend->mode, *p_value, value, blend->influence); - } - - return true; -} - -/* Finish deferred quaternion blending. */ -static void nlaeval_blend_flush(NlaBlendData *blend) -{ - NlaEvalChannel *nec; - - while ((nec = blend->blend_queue)) { - blend->blend_queue = nec->next_blend; - nec->in_blend = false; - - NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec); - NlaEvalChannelSnapshot *blend_snapshot = nec->blend_snapshot; - - if (nec->mix_mode == NEC_MIX_QUATERNION) { - nla_combine_quaternion( - nec_snapshot->values, blend_snapshot->values, blend->influence, nec_snapshot->values); - } - else { - BLI_assert(!"mix quaternion"); - } - } -} - /* Blend the specified snapshots into the target, and free the input snapshots. */ static void nlaeval_snapshot_mix_and_free(NlaEvalData *nlaeval, NlaEvalSnapshot *out, @@ -1857,6 +1767,45 @@ static void nlaeval_fmodifiers_split_stacks(ListBase *list1, ListBase *list2) /* ---------------------- */ +/** Fills \a r_snapshot with the \a action's evaluated fcurve values with modifiers applied. */ +static void nlasnapshot_from_action(PointerRNA *ptr, + NlaEvalData *channels, + ListBase *modifiers, + bAction *action, + const float evaltime, + NlaEvalSnapshot *r_snapshot) +{ + FCurve *fcu; + + action_idcode_patch_check(ptr->owner_id, action); + + /* Evaluate modifiers which modify time to evaluate the base curves at. */ + FModifiersStackStorage storage; + storage.modifier_count = BLI_listbase_count(modifiers); + storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(modifiers); + storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier); + + const float modified_evaltime = evaluate_time_fmodifiers( + &storage, modifiers, NULL, 0.0f, evaltime); + + for (fcu = action->curves.first; fcu; fcu = fcu->next) { + if (!is_fcurve_evaluatable(fcu)) { + continue; + } + + NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path); + + NlaEvalChannelSnapshot *necs = nlaeval_snapshot_ensure_channel(r_snapshot, nec); + if (!nlaevalchan_validate_index_ex(nec, fcu->array_index)) { + continue; + } + + float value = evaluate_fcurve(fcu, modified_evaltime); + evaluate_value_fmodifiers(&storage, modifiers, fcu, &value, evaltime); + necs->values[fcu->array_index] = value; + } +} + /* evaluate action-clip strip */ static void nlastrip_evaluate_actionclip(PointerRNA *ptr, NlaEvalData *channels, @@ -1864,10 +1813,8 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot) { - ListBase tmp_modifiers = {NULL, NULL}; + NlaStrip *strip = nes->strip; - FCurve *fcu; - float evaltime; /* sanity checks for action */ if (strip == NULL) { @@ -1879,54 +1826,20 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr, return; } - action_idcode_patch_check(ptr->owner_id, strip->act); + ListBase tmp_modifiers = {NULL, NULL}; /* join this strip's modifiers to the parent's modifiers (own modifiers first) */ nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers); - /* evaluate strip's modifiers which modify time to evaluate the base curves at */ - FModifiersStackStorage storage; - storage.modifier_count = BLI_listbase_count(&tmp_modifiers); - storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(&tmp_modifiers); - storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier); + NlaEvalSnapshot strip_snapshot; + nlaeval_snapshot_init(&strip_snapshot, channels, NULL); - evaltime = evaluate_time_fmodifiers(&storage, &tmp_modifiers, NULL, 0.0f, strip->strip_time); + nlasnapshot_from_action( + ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot); + nlasnapshot_blend( + channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot); - NlaBlendData blend = { - .snapshot = snapshot, - .mode = strip->blendmode, - .influence = strip->influence, - }; - - /* Evaluate all the F-Curves in the action, - * saving the relevant pointers to data that will need to be used. */ - for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) { - - if (!is_fcurve_evaluatable(fcu)) { - continue; - } - - /* evaluate the F-Curve's value for the time given in the strip - * NOTE: we use the modified time here, since strip's F-Curve Modifiers - * are applied on top of this. - */ - float value = evaluate_fcurve(fcu, evaltime); - - /* apply strip's F-Curve Modifiers on this value - * NOTE: we apply the strip's original evaluation time not the modified one - * (as per standard F-Curve eval) - */ - evaluate_value_fmodifiers(&storage, &tmp_modifiers, fcu, &value, strip->strip_time); - - /* Get an NLA evaluation channel to work with, - * and accumulate the evaluated value with the value(s) - * stored in this channel if it has been used already. */ - NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path); - - nlaeval_blend_value(&blend, nec, fcu->array_index, value); - } - - nlaeval_blend_flush(&blend); + nlaeval_snapshot_free_data(&strip_snapshot); /* unlink this strip's modifiers from the parent's modifiers again */ nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers); @@ -2597,6 +2510,67 @@ static void animsys_calculate_nla(PointerRNA *ptr, /* ---------------------- */ +/** Blends the \a lower_snapshot with the \a upper_snapshot into \a r_blended_snapshot according + * to the given \a upper_blendmode and \a upper_influence. */ +void nlasnapshot_blend(NlaEvalData *eval_data, + NlaEvalSnapshot *lower_snapshot, + NlaEvalSnapshot *upper_snapshot, + const short upper_blendmode, + const float upper_influence, + NlaEvalSnapshot *r_blended_snapshot) +{ + nlaeval_snapshot_ensure_size(r_blended_snapshot, eval_data->num_channels); + + const bool zero_upper_influence = IS_EQF(upper_influence, 0.0f); + + LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) { + const int length = nec->base_snapshot.length; + + NlaEvalChannelSnapshot *upper_necs = nlaeval_snapshot_get(upper_snapshot, nec->index); + NlaEvalChannelSnapshot *lower_necs = nlaeval_snapshot_get(lower_snapshot, nec->index); + if (upper_necs == NULL && lower_necs == NULL) { + continue; + } + + /** Blend with lower_snapshot's base or default. */ + if (lower_necs == NULL) { + lower_necs = nlaeval_snapshot_find_channel(lower_snapshot->base, nec); + } + + NlaEvalChannelSnapshot *result_necs = nlaeval_snapshot_ensure_channel(r_blended_snapshot, nec); + + if (upper_necs == NULL || zero_upper_influence) { + memcpy(result_necs->values, lower_necs->values, length * sizeof(float)); + continue; + } + + if (upper_blendmode == NLASTRIP_MODE_COMBINE) { + const int mix_mode = nec->mix_mode; + if (mix_mode == NEC_MIX_QUATERNION) { + nla_combine_quaternion( + lower_necs->values, upper_necs->values, upper_influence, result_necs->values); + } + else { + for (int j = 0; j < length; j++) { + result_necs->values[j] = nla_combine_value(mix_mode, + nec->base_snapshot.values[j], + lower_necs->values[j], + upper_necs->values[j], + upper_influence); + } + } + } + else { + for (int j = 0; j < length; j++) { + result_necs->values[j] = nla_blend_value( + upper_blendmode, lower_necs->values[j], upper_necs->values[j], upper_influence); + } + } + } +} + +/* ---------------------- */ + /** * Prepare data necessary to compute correct keyframe values for NLA strips * with non-Replace mode or influence different from 1. diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c index 1bce9ad8e35..d1bf523acef 100644 --- a/source/blender/blenkernel/intern/fcurve_driver.c +++ b/source/blender/blenkernel/intern/fcurve_driver.c @@ -240,7 +240,7 @@ bool driver_get_variable_property(ChannelDriver *driver, ptr = PointerRNA_NULL; prop = NULL; /* OK. */ } - else if (RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { + else if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { /* OK. */ } else { diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 9e8e515e1a3..1c9430a35a2 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -477,6 +477,13 @@ static void lib_override_linked_group_tag( BKE_main_relations_create(bmain, 0); } + if ((id->tag & LIB_TAG_MISSING)) { + id->tag |= missing_tag; + } + else { + id->tag |= tag; + } + if (ELEM(GS(id->name), ID_OB, ID_GR)) { LibOverrideGroupTagData data = {.id_root = id, .tag = tag, .missing_tag = missing_tag}; /* Tag all collections and objects. */ @@ -572,6 +579,8 @@ static void lib_override_local_group_tag(Main *bmain, const uint tag, const uint missing_tag) { + id->tag |= tag; + LibOverrideGroupTagData data = {.id_root = id, .tag = tag, .missing_tag = missing_tag}; /* Tag all local overrides in id_root's group. */ BKE_library_foreach_ID_link( @@ -580,8 +589,6 @@ static void lib_override_local_group_tag(Main *bmain, static bool lib_override_library_create_do(Main *bmain, ID *id_root) { - id_root->tag |= LIB_TAG_DOIT; - BKE_main_relations_create(bmain, 0); lib_override_linked_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_MISSING, false); @@ -780,7 +787,6 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_ { BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root)); - id_root->tag |= LIB_TAG_DOIT; ID *id_root_reference = id_root->override_library->reference; lib_override_local_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_MISSING); @@ -956,9 +962,6 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root) { BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root)); - /* Tag all collections and objects, as well as other IDs using them. */ - id_root->tag |= LIB_TAG_DOIT; - /* Tag all library overrides in the chains of dependencies from the given root one. */ lib_override_local_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_DOIT); diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 8be26fc8547..1fd51544ba7 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -416,13 +416,14 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) return ELEM(id_type_used, ID_MA); case ID_SIM: return ELEM(id_type_used, ID_OB, ID_IM); + case ID_WM: + return ELEM(id_type_used, ID_SCE, ID_WS); case ID_IM: case ID_VF: case ID_TXT: case ID_SO: case ID_AR: case ID_AC: - case ID_WM: case ID_PAL: case ID_PC: case ID_CF: diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 2dbfa85b8e1..3c9c255cacd 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4774,6 +4774,7 @@ static void registerGeometryNodes() register_node_type_geo_sample_texture(); register_node_type_geo_points_to_volume(); register_node_type_geo_collection_info(); + register_node_type_geo_is_viewport(); } static void registerFunctionNodes() diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h index 034f3f39fd3..488bc5dc98b 100644 --- a/source/blender/blenkernel/nla_private.h +++ b/source/blender/blenkernel/nla_private.h @@ -106,12 +106,8 @@ typedef struct NlaEvalChannel { int index; bool is_array; - bool in_blend; char mix_mode; - struct NlaEvalChannel *next_blend; - NlaEvalChannelSnapshot *blend_snapshot; - /* Associated with the RNA property's value(s), marks which elements are affected by NLA. */ NlaValidMask domain; @@ -186,6 +182,13 @@ void nladata_flush_channels(PointerRNA *ptr, NlaEvalSnapshot *snapshot, const bool flush_to_original); +void nlasnapshot_blend(NlaEvalData *eval_data, + NlaEvalSnapshot *lower_snapshot, + NlaEvalSnapshot *upper_snapshot, + const short upper_blendmode, + const float upper_influence, + NlaEvalSnapshot *r_blended_snapshot); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index f1b15b61d06..0b0594c7f4a 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -140,7 +140,6 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) */ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, - const bool use_assets_only, int *r_tot_names) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index f474ae542d9..cf78959e712 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2484,11 +2484,11 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, /** * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing). */ -static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph, - ARegion *region, - View3D *v3d, - GPUViewport *viewport, - const bool use_opengl_context) +static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph, + ARegion *region, + View3D *v3d, + GPUViewport *viewport, + const bool use_opengl_context) { Scene *scene = DEG_get_evaluated_scene(depsgraph); RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); @@ -2611,7 +2611,7 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph, } } - drw_draw_depth_loop_imp(depsgraph, region, v3d, viewport, use_opengl_context); + drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, use_opengl_context); } /** @@ -2627,7 +2627,7 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph, use_drw_engine(&draw_engine_gpencil_type); - drw_draw_depth_loop_imp(depsgraph, region, v3d, viewport, true); + drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, true); } void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const rcti *rect) diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index e0262371559..d54265aa292 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -27,6 +27,7 @@ set(INC ../../makesrna ../../sequencer ../../windowmanager + ../../../../intern/clog ../../../../intern/glew-mx ../../../../intern/guardedalloc ) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 2a2803c58dd..fa485dc6b4b 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -23,6 +23,8 @@ #include "MEM_guardedalloc.h" +#include "CLG_log.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_collection_types.h" @@ -92,6 +94,8 @@ #include "outliner_intern.h" +static CLG_LogRef LOG = {"ed.outliner.tools"}; + /* -------------------------------------------------------------------- */ /** \name ID/Library/Data Set/Un-link Utilities * \{ */ @@ -824,6 +828,9 @@ static void id_override_library_create_fn(bContext *C, BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); } } + else { + CLOG_WARN(&LOG, "Could not create library override for data block '%s'", id_root->name); + } } static void id_override_library_reset_fn(bContext *C, @@ -852,6 +859,9 @@ static void id_override_library_reset_fn(bContext *C, WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); } + else { + CLOG_WARN(&LOG, "Could not reset library override of data block '%s'", id_root->name); + } } static void id_override_library_resync_fn(bContext *C, @@ -883,6 +893,9 @@ static void id_override_library_resync_fn(bContext *C, BKE_lib_override_library_resync(bmain, scene, CTX_data_view_layer(C), id_root); } + else { + CLOG_WARN(&LOG, "Could not resync library override of data block '%s'", id_root->name); + } } static void id_override_library_delete_fn(bContext *C, @@ -914,6 +927,9 @@ static void id_override_library_delete_fn(bContext *C, BKE_lib_override_library_delete(bmain, id_root); } + else { + CLOG_WARN(&LOG, "Could not delete library override of data block '%s'", id_root->name); + } } static void id_fake_user_set_fn(bContext *UNUSED(C), @@ -1789,21 +1805,44 @@ static bool outliner_id_operation_item_poll(bContext *C, const int enum_value) { SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); + TreeElement *te = get_target_element(space_outliner); + TreeStoreElem *tselem = TREESTORE(te); + if (!TSE_IS_REAL_ID(tselem)) { + return false; + } + + Object *ob = NULL; + if (GS(tselem->id->name) == ID_OB) { + ob = (Object *)tselem->id; + } switch (enum_value) { case OUTLINER_IDOP_MARK_ASSET: case OUTLINER_IDOP_CLEAR_ASSET: return U.experimental.use_asset_browser; case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE: + if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) { + return true; + } + return false; case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: - return true; + if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id) || (ID_IS_LINKED(tselem->id))) { + return true; + } + return false; + case OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT: + if (ob != NULL && ob->proxy != NULL) { + return true; + } + return false; case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: - return true; case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY: - return true; case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY: - return true; + if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) { + return true; + } + return false; case OUTLINER_IDOP_SINGLE: if (!space_outliner || ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) { return true; diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index fc8e823f050..4b7b16c2986 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -549,10 +549,10 @@ static void applyObjectConstraintSize(TransInfo *t, } } -static void constraints_rotation_imp(TransInfo *t, - float axismtx[3][3], - float r_vec[3], - float *r_angle) +static void constraints_rotation_impl(TransInfo *t, + float axismtx[3][3], + float r_vec[3], + float *r_angle) { BLI_assert(t->con.mode & CON_APPLY); int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2); @@ -560,15 +560,15 @@ static void constraints_rotation_imp(TransInfo *t, switch (mode) { case CON_AXIS0: case (CON_AXIS1 | CON_AXIS2): - negate_v3_v3(r_vec, axismtx[0]); + copy_v3_v3(r_vec, axismtx[0]); break; case CON_AXIS1: case (CON_AXIS0 | CON_AXIS2): - negate_v3_v3(r_vec, axismtx[1]); + copy_v3_v3(r_vec, axismtx[1]); break; case CON_AXIS2: case (CON_AXIS0 | CON_AXIS1): - negate_v3_v3(r_vec, axismtx[2]); + copy_v3_v3(r_vec, axismtx[2]); break; } /* don't flip axis if asked to or if num input */ @@ -598,7 +598,7 @@ static void applyAxisConstraintRot( TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float vec[3], float *angle) { if (!td && t->con.mode & CON_APPLY) { - constraints_rotation_imp(t, t->spacemtx, vec, angle); + constraints_rotation_impl(t, t->spacemtx, vec, angle); } } @@ -637,7 +637,7 @@ static void applyObjectConstraintRot( axismtx = td->axismtx; } - constraints_rotation_imp(t, axismtx, vec, angle); + constraints_rotation_impl(t, axismtx, vec, angle); } } diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index adc2d03e2dc..51802a1e769 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -304,7 +304,7 @@ void recalcData_nla(TransInfo *t) for (i = 0; i < tc->data_len; i++, tdn++) { NlaStrip *strip = tdn->strip; PointerRNA strip_ptr; - short pExceeded, nExceeded, iter; + short iter; int delta_y1, delta_y2; /* if this tdn has no handles, that means it is just a dummy that should be skipped */ @@ -358,21 +358,31 @@ void recalcData_nla(TransInfo *t) * * this is done as a iterative procedure (done 5 times max for now) */ + NlaStrip *prev = strip->prev; + while (prev != NULL && (prev->type & NLASTRIP_TYPE_TRANSITION)) { + prev = prev->prev; + } + + NlaStrip *next = strip->next; + while (next != NULL && (next->type & NLASTRIP_TYPE_TRANSITION)) { + next = next->next; + } + for (iter = 0; iter < 5; iter++) { - pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) && - (tdn->h1[0] < strip->prev->end)); - nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) && - (tdn->h2[0] > strip->next->start)); + + const bool pExceeded = (prev != NULL) && (tdn->h1[0] < prev->end); + const bool nExceeded = (next != NULL) && (tdn->h2[0] > next->start); if ((pExceeded && nExceeded) || (iter == 4)) { - /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise) + /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a + * compromise) * - Simply crop strip to fit within the bounds of the strips bounding it * - If there were no neighbors, clear the transforms * (make it default to the strip's current values). */ - if (strip->prev && strip->next) { - tdn->h1[0] = strip->prev->end; - tdn->h2[0] = strip->next->start; + if (prev && next) { + tdn->h1[0] = prev->end; + tdn->h2[0] = next->start; } else { tdn->h1[0] = strip->start; @@ -381,14 +391,14 @@ void recalcData_nla(TransInfo *t) } else if (nExceeded) { /* move backwards */ - float offset = tdn->h2[0] - strip->next->start; + float offset = tdn->h2[0] - next->start; tdn->h1[0] -= offset; tdn->h2[0] -= offset; } else if (pExceeded) { /* more forwards */ - float offset = strip->prev->end - tdn->h1[0]; + float offset = prev->end - tdn->h1[0]; tdn->h1[0] += offset; tdn->h2[0] += offset; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index f648369bc31..b092b3e3e0b 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -428,7 +428,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve BLI_assert(is_zero_v4(t->values_modal_offset)); - bool use_orient_axis = false; bool t_values_set_is_array = false; if (op && (prop = RNA_struct_find_property(op->ptr, "value")) && @@ -453,11 +452,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } - if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) { - t->orient_axis = RNA_property_enum_get(op->ptr, prop); - use_orient_axis = true; - } - if (op && (prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) { bool constraint_axis[3] = {false, false, false}; if (t->flag & T_INPUT_IS_VALUES_FINAL) { @@ -466,9 +460,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve * orientation is more intuitive in the Redo Panel. */ constraint_axis[0] = constraint_axis[1] = constraint_axis[2] = true; } - else if (use_orient_axis) { - constraint_axis[t->orient_axis] = true; - } } else if (RNA_property_is_set(op->ptr, prop)) { RNA_property_boolean_get_array(op->ptr, prop, constraint_axis); @@ -497,6 +488,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve short orient_type_set = V3D_ORIENT_GLOBAL; short orient_type_matrix_set = -1; + bool use_orient_axis = false; + if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) { TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT]; orient_type_scene = orient_slot->type; @@ -508,6 +501,11 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve short orient_type_default = orient_type_scene; + if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) { + t->orient_axis = RNA_property_enum_get(op->ptr, prop); + use_orient_axis = true; + } + if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) { t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop); } diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 0a4448f82f9..eec0ce42f3c 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1322,16 +1322,16 @@ void drawDial3d(const TransInfo *t) if (tc->mode & CON_APPLY) { if (tc->mode & CON_AXIS0) { axis_idx = MAN_AXIS_ROT_X; - copy_v3_v3(mat_basis[2], t->spacemtx[0]); + negate_v3_v3(mat_basis[2], t->spacemtx[0]); } else if (tc->mode & CON_AXIS1) { axis_idx = MAN_AXIS_ROT_Y; - copy_v3_v3(mat_basis[2], t->spacemtx[1]); + negate_v3_v3(mat_basis[2], t->spacemtx[1]); } else { BLI_assert((tc->mode & CON_AXIS2) != 0); axis_idx = MAN_AXIS_ROT_Z; - copy_v3_v3(mat_basis[2], t->spacemtx[2]); + negate_v3_v3(mat_basis[2], t->spacemtx[2]); } } else { diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index 7ccfd0149bd..dd212af7caf 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -49,7 +49,7 @@ static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *event) { BLI_assert(t->mode == TFM_SEQ_SLIDE); - wmKeyMapItem *kmi = t->custom.mode.data; + const wmKeyMapItem *kmi = t->custom.mode.data; if (kmi && event->type == kmi->type && event->val == kmi->val) { /* Allows the 'Expand to fit' effect to be enabled as a toogle. */ t->flag ^= T_ALT_TRANSFORM; @@ -73,7 +73,7 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA ofs += BLI_snprintf( str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text); - wmKeyMapItem *kmi = t->custom.mode.data; + const wmKeyMapItem *kmi = t->custom.mode.data; if (kmi) { ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs); } @@ -158,7 +158,7 @@ void initSeqSlide(TransInfo *t) if (t->keymap) { /* Workaround to use the same key as the modal keymap. */ - t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE); + t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE); } } /** \} */ diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c index 2a5c631df41..bccf4db66af 100644 --- a/source/blender/editors/transform/transform_mode_shrink_fatten.c +++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c @@ -49,7 +49,7 @@ static eRedrawFlag shrinkfatten_handleEvent(struct TransInfo *t, const wmEvent *event) { BLI_assert(t->mode == TFM_SHRINKFATTEN); - wmKeyMapItem *kmi = t->custom.mode.data; + const wmKeyMapItem *kmi = t->custom.mode.data; if (kmi && event->type == kmi->type && event->val == kmi->val) { /* Allows the 'Even Thickness' effect to be enabled as a toogle. */ t->flag ^= T_ALT_TRANSFORM; @@ -90,7 +90,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) } ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs); - wmKeyMapItem *kmi = t->custom.mode.data; + const wmKeyMapItem *kmi = t->custom.mode.data; if (kmi) { ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs); } @@ -150,7 +150,7 @@ void initShrinkFatten(TransInfo *t) if (t->keymap) { /* Workaround to use the same key as the modal keymap. */ - t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE); + t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE); } } } diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh index 5a7dfadf537..a854e63288d 100644 --- a/source/blender/functions/FN_cpp_type.hh +++ b/source/blender/functions/FN_cpp_type.hh @@ -929,4 +929,9 @@ inline std::unique_ptr create_cpp_type(StringRef name, const T &d static std::unique_ptr cpp_type = blender::fn::create_cpp_type( \ STRINGIFY(IDENTIFIER), default_value); \ return *cpp_type; \ + } \ + /* Support using `CPPType::get()`. Otherwise the caller would have to remove const. */ \ + template<> const blender::fn::CPPType &blender::fn::CPPType::get() \ + { \ + return blender::fn::CPPType::get(); \ } diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index f07af2c14a0..a3aaf3ee937 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -215,7 +215,7 @@ enum { (WM_OUTLINER_SYNC_SELECT_FROM_OBJECT | WM_OUTLINER_SYNC_SELECT_FROM_EDIT_BONE | \ WM_OUTLINER_SYNC_SELECT_FROM_POSE_BONE | WM_OUTLINER_SYNC_SELECT_FROM_SEQUENCE) -#define WM_KEYCONFIG_STR_DEFAULT "blender" +#define WM_KEYCONFIG_STR_DEFAULT "Blender" /* IME is win32 only! */ #if !defined(WIN32) && !defined(DNA_DEPRECATED) diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 3ebcb09a65d..5541fe3053f 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -72,6 +72,12 @@ const EnumPropertyItem rna_enum_window_cursor_items[] = { # include "WM_types.h" +/* Needed since RNA doesn't use `const` in function signatures. */ +static bool rna_KeyMapItem_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2) +{ + return WM_keymap_item_compare(k1, k2); +} + static void rna_KeyMapItem_to_string(wmKeyMapItem *kmi, bool compact, char *result) { WM_keymap_item_to_string(kmi, compact, result, UI_MAX_SHORTCUT_STR); @@ -1103,7 +1109,7 @@ void RNA_api_keymapitem(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; - func = RNA_def_function(srna, "compare", "WM_keymap_item_compare"); + func = RNA_def_function(srna, "compare", "rna_KeyMapItem_compare"); parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_boolean(func, "result", 0, "Comparison result", ""); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 9982962cabd..aedca4b34fb 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -153,6 +153,7 @@ set(SRC geometry/nodes/node_geo_collection_info.cc geometry/nodes/node_geo_common.cc geometry/nodes/node_geo_edge_split.cc + geometry/nodes/node_geo_is_viewport.cc geometry/nodes/node_geo_join_geometry.cc geometry/nodes/node_geo_object_info.cc geometry/nodes/node_geo_point_distribute.cc diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index 178831d5d96..9b391ab7981 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -50,6 +50,7 @@ void register_node_type_geo_align_rotation_to_vector(void); void register_node_type_geo_sample_texture(void); void register_node_type_geo_points_to_volume(void); void register_node_type_geo_collection_info(void); +void register_node_type_geo_is_viewport(void); #ifdef __cplusplus } diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index cbc5f715db0..f9730af0c08 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -292,6 +292,7 @@ DefNode(GeometryNode, GEO_NODE_POINT_TRANSLATE, def_geo_point_translate, "POINT_ DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE, def_geo_attribute_sample_texture, "ATTRIBUTE_SAMPLE_TEXTURE", AttributeSampleTexture, "Attribute Sample Texture", "") DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POINTS_TO_VOLUME", PointsToVolume, "Points to Volume", "") DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "") +DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "") /* undefine macros */ #undef DefNode diff --git a/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc b/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc new file mode 100644 index 00000000000..667beaa1722 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc @@ -0,0 +1,47 @@ +/* + * 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 "node_geometry_util.hh" + +#include "DEG_depsgraph_query.h" + +static bNodeSocketTemplate geo_node_is_viewport_out[] = { + {SOCK_BOOLEAN, N_("Is Viewport")}, + {-1, ""}, +}; + +namespace blender::nodes { + +static void geo_node_is_viewport_exec(GeoNodeExecParams params) +{ + const Depsgraph *depsgraph = params.depsgraph(); + const eEvaluationMode mode = DEG_get_mode(depsgraph); + const bool is_viewport = mode == DAG_EVAL_VIEWPORT; + + params.set_output("Is Viewport", is_viewport); +} + +} // namespace blender::nodes + +void register_node_type_geo_is_viewport() +{ + static bNodeType ntype; + + geo_node_type_base(&ntype, GEO_NODE_IS_VIEWPORT, "Is Viewport", NODE_CLASS_INPUT, 0); + node_type_socket_templates(&ntype, nullptr, geo_node_is_viewport_out); + ntype.geometry_node_execute = blender::nodes::geo_node_is_viewport_exec; + nodeRegisterType(&ntype); +} diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 1a174549d66..b2603c75c3f 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -169,12 +169,12 @@ static PyObject *py_shader_uniform_block_from_name(BPyGPUShader *self, PyObject return PyLong_FromLong(uniform); } -static bool py_shader_uniform_vector_imp(PyObject *args, - int elem_size, - int *r_location, - int *r_length, - int *r_count, - Py_buffer *r_pybuffer) +static bool py_shader_uniform_vector_impl(PyObject *args, + int elem_size, + int *r_location, + int *r_length, + int *r_count, + Py_buffer *r_pybuffer) { PyObject *buffer; @@ -223,7 +223,7 @@ static PyObject *py_shader_uniform_vector_float(BPyGPUShader *self, PyObject *ar Py_buffer pybuffer; - if (!py_shader_uniform_vector_imp(args, sizeof(float), &location, &length, &count, &pybuffer)) { + if (!py_shader_uniform_vector_impl(args, sizeof(float), &location, &length, &count, &pybuffer)) { return NULL; } @@ -244,7 +244,7 @@ static PyObject *py_shader_uniform_vector_int(BPyGPUShader *self, PyObject *args Py_buffer pybuffer; - if (!py_shader_uniform_vector_imp(args, sizeof(int), &location, &length, &count, &pybuffer)) { + if (!py_shader_uniform_vector_impl(args, sizeof(int), &location, &length, &count, &pybuffer)) { return NULL; } diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index 69a6bd1ebbf..39d1fba2dc9 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -173,7 +173,7 @@ static PyTypeObject bpy_lib_Type = { PyDoc_STRVAR( bpy_lib_load_doc, - ".. method:: load(filepath, link=False, assets_only=False, relative=False)\n" + ".. method:: load(filepath, link=False, relative=False, assets_only=False)\n" "\n" " Returns a context manager which exposes 2 library objects on entering.\n" " Each object has attributes matching bpy.data which are lists of strings to be linked.\n" @@ -182,10 +182,10 @@ PyDoc_STRVAR( " :type filepath: string\n" " :arg link: When False reference to the original file is lost.\n" " :type link: bool\n" - " :arg assets_only: If True, only list data-blocks marked as assets.\n" - " :type assets_only: bool\n" " :arg relative: When True the path is stored relative to the open blend file.\n" - " :type relative: bool\n"); + " :type relative: bool\n" + " :arg assets_only: If True, only list data-blocks marked as assets.\n" + " :type assets_only: bool\n"); static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { Main *bmain = CTX_data_main(BPY_context_get()); diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c index 8567835f55c..d9515bca2d5 100644 --- a/source/blender/render/intern/pipeline.c +++ b/source/blender/render/intern/pipeline.c @@ -2007,6 +2007,9 @@ void RE_RenderFrame(Render *re, G.is_rendering = false; } +#ifdef WITH_FREESTYLE + +/* Not freestyle specific, currently only used by free-style. */ static void change_renderdata_engine(Render *re, const char *new_engine) { if (!STREQ(re->r.engine, new_engine)) { @@ -2018,7 +2021,6 @@ static void change_renderdata_engine(Render *re, const char *new_engine) } } -#ifdef WITH_FREESTYLE static bool use_eevee_for_freestyle_render(Render *re) { RenderEngineType *type = RE_engines_find(re->r.engine); diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index 15be21bdbc4..564afe084b9 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -59,7 +59,7 @@ wmKeyMapItem *WM_keymap_add_item( wmKeyMapItem *WM_keymap_add_item_copy(struct wmKeyMap *keymap, wmKeyMapItem *kmi_src); bool WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); -int WM_keymap_item_to_string(wmKeyMapItem *kmi, +int WM_keymap_item_to_string(const wmKeyMapItem *kmi, const bool compact, char *result, const int result_len); @@ -86,7 +86,7 @@ bool WM_keymap_remove(struct wmKeyConfig *keyconfig, struct wmKeyMap *keymap); bool WM_keymap_poll(struct bContext *C, struct wmKeyMap *keymap); wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id); -bool WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); +bool WM_keymap_item_compare(const struct wmKeyMapItem *k1, const struct wmKeyMapItem *k2); /* keymap_utils.c */ @@ -111,13 +111,13 @@ void WM_keymap_add_context_enum_set_items(wmKeyMap *keymap, wmKeyMap *WM_keymap_guess_from_context(const struct bContext *C); wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname); -bool WM_keymap_uses_event_modifier(wmKeyMap *keymap, const int event_modifier); +bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier); void WM_keymap_fix_linking(void); /* Modal Keymap */ -int WM_modalkeymap_items_to_string(struct wmKeyMap *km, +int WM_modalkeymap_items_to_string(const struct wmKeyMap *km, const int propvalue, const bool compact, char *result, @@ -142,7 +142,7 @@ wmKeyMapItem *WM_modalkeymap_add_item( struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); wmKeyMapItem *WM_modalkeymap_add_item_str( struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value); -wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue); +const wmKeyMapItem *WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int propvalue); void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); /* Keymap Editor */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 8bfec0dc5c9..fcb13fff0a5 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -949,9 +949,9 @@ wmKeyMapItem *WM_modalkeymap_add_item_str( return kmi; } -static wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(wmKeyMap *km, - wmKeyMapItem *kmi, - const int propvalue) +static const wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(const wmKeyMap *km, + const wmKeyMapItem *kmi, + const int propvalue) { if (km->flag & KEYMAP_MODAL) { kmi = kmi ? kmi->next : km->items.first; @@ -968,7 +968,7 @@ static wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(wmKeyMap *km, return NULL; } -wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue) +const wmKeyMapItem *WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int propvalue) { return wm_modalkeymap_find_propvalue_iter(km, NULL, propvalue); } @@ -1201,7 +1201,7 @@ int WM_keymap_item_raw_to_string(const short shift, #undef ADD_SEP } -int WM_keymap_item_to_string(wmKeyMapItem *kmi, +int WM_keymap_item_to_string(const wmKeyMapItem *kmi, const bool compact, char *result, const int result_len) @@ -1218,14 +1218,17 @@ int WM_keymap_item_to_string(wmKeyMapItem *kmi, result_len); } -int WM_modalkeymap_items_to_string( - wmKeyMap *km, const int propvalue, const bool compact, char *result, const int result_len) +int WM_modalkeymap_items_to_string(const wmKeyMap *km, + const int propvalue, + const bool compact, + char *result, + const int result_len) { int totlen = 0; bool add_sep = false; if (km) { - wmKeyMapItem *kmi; + const wmKeyMapItem *kmi; /* Find all shortcuts related to that propvalue! */ for (kmi = WM_modalkeymap_find_propvalue(km, propvalue); kmi && totlen < (result_len - 2); @@ -1654,7 +1657,7 @@ wmKeyMapItem *WM_key_event_operator_from_keymap(wmKeyMap *keymap, }); } -bool WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2) +bool WM_keymap_item_compare(const wmKeyMapItem *k1, const wmKeyMapItem *k2) { if (k1->flag & KMI_INACTIVE || k2->flag & KMI_INACTIVE) { return 0; diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c index 953fb9fed79..865889e7e64 100644 --- a/source/blender/windowmanager/intern/wm_keymap_utils.c +++ b/source/blender/windowmanager/intern/wm_keymap_utils.c @@ -477,7 +477,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) return km; } -static bool wm_keymap_item_uses_modifier(wmKeyMapItem *kmi, const int event_modifier) +static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int event_modifier) { if (kmi->ctrl != KM_ANY) { if ((kmi->ctrl == KM_NOTHING) != ((event_modifier & KM_CTRL) == 0)) { @@ -505,9 +505,9 @@ static bool wm_keymap_item_uses_modifier(wmKeyMapItem *kmi, const int event_modi return true; } -bool WM_keymap_uses_event_modifier(wmKeyMap *keymap, const int event_modifier) +bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier) { - LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { + LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &keymap->items) { if ((kmi->flag & KMI_INACTIVE) == 0) { if (wm_keymap_item_uses_modifier(kmi, event_modifier)) { return true; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 42fd214543f..c4b50f1c889 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -560,6 +560,13 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, wmWindow *win, bool is_dialog) { + /* On Windows, if there is a parent window then force is_dialog. Otherwise the parent + handle is not used in window creation and they do not stay on top of parents. */ +#ifdef WIN32 + if (win->parent) { + is_dialog = true; + } +#endif /* a new window is created when pageflip mode is required for a window */ GHOST_GLSettings glSettings = {0}; @@ -858,13 +865,15 @@ wmWindow *WM_window_open_temp(bContext *C, /* changes rect to fit within desktop */ wm_window_check_position(&rect); - /* Reuse temporary or dialog window if one is open (but don't use a dialog for a regular - * temporary window, or vice versa). */ + /* Reuse temporary windows when they share the same title. */ wmWindow *win = NULL; LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { - if (WM_window_is_temp_screen(win_iter) && - (dialog == GHOST_IsDialogWindow(win_iter->ghostwin))) { - win = win_iter; + if (WM_window_is_temp_screen(win_iter)) { + char *wintitle = GHOST_GetTitle(win_iter->ghostwin); + if (strcmp(title, wintitle) == 0) { + win = win_iter; + } + free(wintitle); } } diff --git a/source/tools b/source/tools index d7d7e9d41f7..dd131bc4f95 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit d7d7e9d41f7499aa4639f96c843156ff834385ba +Subproject commit dd131bc4f95103efa60ce11cafbf174efd7b3d4e