From 62d9dabc7db4e241df9fc0edfc571b929493c331 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Fri, 9 Jul 2021 19:23:08 -0400 Subject: UI: Clip: Fix checkbox wrongly greying out entire column The Pattern and Search display options in the Clip Editor display settings are independent and should not be grayed out since those options remain relevant even with path display turned off. Alternative solution were propoesed in D11630 and D11715 but each of those patches had downsides. This solution is the simplest and does not break muscle memory. --- release/scripts/startup/bl_ui/space_clip.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index ca7f9cdc100..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() -- cgit v1.2.3 From 2a41ab5e6ca48c7ae2392c567c74162e34a74c9b Mon Sep 17 00:00:00 2001 From: Johnny Matthews Date: Mon, 12 Jul 2021 13:10:56 -0400 Subject: Geometry Nodes: Curve Primitive Quadrilateral This commit adds a curve primitive node for creating squares, rectangles, trapezoids, kites, and parallelograms. It also includes a mode where the four points are just vector inputs. Differential Revision: https://developer.blender.org/D11665 --- release/scripts/startup/nodeitems_builtins.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index b1ed1441245..d617cfab988 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -516,6 +516,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeCurveStar"), NodeItem("GeometryNodeCurveSpiral"), NodeItem("GeometryNodeCurveQuadraticBezier"), + NodeItem("GeometryNodeCurvePrimitiveQuadrilateral"), NodeItem("GeometryNodeCurvePrimitiveBezierSegment"), ]), GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=[ @@ -559,6 +560,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeMeshLine"), NodeItem("GeometryNodeMeshUVSphere"), ]), + GeometryNodeCategory("GEO_POINT", "Point", items=[ NodeItem("GeometryNodePointDistribute"), NodeItem("GeometryNodePointInstance"), -- cgit v1.2.3 From 3b6ee8cee7080af200e25e944fe30d310240e138 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Jul 2021 12:10:34 -0400 Subject: Refactor: Move vertex group names to object data This commit moves the storage of `bDeformGroup` and the active index to `Mesh`, `Lattice`, and `bGPdata` instead of `Object`. Utility functions are added to allow easy access to the vertex groups given an object or an ID. As explained in T88951, the list of vertex group names is currently stored separately per object, even though vertex group data is stored on the geometry. This tends to complicate code and cause bugs, especially as geometry is created procedurally and tied less closely to an object. The "Copy Vertex Groups to Linked" operator is removed, since they are stored on the geometry anyway. This patch leaves the object-level python API for vertex groups in place. Creating a geometry-level RNA API can be a separate step; the changes in this commit are invasive enough as it is. Note that opening a file saved in 3.0 in an earlier version means the vertex groups will not be available. Differential Revision: https://developer.blender.org/D11689 --- release/scripts/startup/bl_ui/properties_data_mesh.py | 1 - 1 file changed, 1 deletion(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index fb8aedd1f49..7f4328bb25a 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -41,7 +41,6 @@ class MESH_MT_vertex_group_context_menu(Menu): ).sort_type = 'BONE_HIERARCHY' layout.separator() layout.operator("object.vertex_group_copy", icon='DUPLICATE') - layout.operator("object.vertex_group_copy_to_linked") layout.operator("object.vertex_group_copy_to_selected") layout.separator() layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT').use_topology = False -- cgit v1.2.3 From d35b14449eed68e3239145627854cabb1e2b93a8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Jul 2021 17:53:26 +1000 Subject: Cleanup: ensure one newline at end of file, strip trailing space --- release/scripts/startup/nodeitems_builtins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index d617cfab988..1d616947db6 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -560,7 +560,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeMeshLine"), NodeItem("GeometryNodeMeshUVSphere"), ]), - + GeometryNodeCategory("GEO_POINT", "Point", items=[ NodeItem("GeometryNodePointDistribute"), NodeItem("GeometryNodePointInstance"), -- cgit v1.2.3 From add6fa09249636cf5709675c9c0ef9a444bb4443 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 9 Jul 2021 12:33:38 +0200 Subject: Assets: Show asset path in asset browser sidebar It's useful to know where an asset is stored in, before this there was no way to tell this. This could probably be displayed nicer in the UI but we're currently unsure how. But at least the information is there now. --- release/scripts/startup/bl_ui/space_filebrowser.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 1ad88744b16..96855cb4a07 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -592,15 +592,26 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel): def draw(self, context): layout = self.layout - active_file = context.active_file - active_asset = asset_utils.SpaceAssetInfo.get_active_asset(context) + asset_file_handle = context.asset_file_handle - if not active_file or not active_asset: + if asset_file_handle is None: layout.label(text="No asset selected", icon='INFO') return - # If the active file is an ID, use its name directly so renaming is possible from right here. - layout.prop(context.id if context.id is not None else active_file, "name", text="") + asset_library = context.asset_library + asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file_handle, asset_library) + + if asset_file_handle.local_id: + # If the active file is an ID, use its name directly so renaming is possible from right here. + layout.prop(asset_file_handle.local_id, "name", text="") + row = layout.row() + row.label(text="Source: Current File") + else: + layout.prop(asset_file_handle, "name", text="") + col = layout.column(align=True) # Just to reduce margin. + col.label(text="Source:") + row = col.row() + row.label(text=asset_lib_path) class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel): -- cgit v1.2.3 From b40e05fcd134e5b9d5aac7ba9e5f45e4e9733607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 2 Jul 2021 10:40:19 +0200 Subject: Assets: Open Blend File operator Add operator 'Open Blend File' to the Asset Browser. This operator: - starts a new Blender process, - opens the blend file containing the asset, - monitors the new Blender process, and when it stops, - reloads the assets to show any changes made. --- release/scripts/startup/bl_operators/assets.py | 83 ++++++++++++++++++++++ release/scripts/startup/bl_ui/space_filebrowser.py | 6 ++ 2 files changed, 89 insertions(+) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_operators/assets.py b/release/scripts/startup/bl_operators/assets.py index 48f07a03773..d2655784afd 100644 --- a/release/scripts/startup/bl_operators/assets.py +++ b/release/scripts/startup/bl_operators/assets.py @@ -18,7 +18,9 @@ # from __future__ import annotations +from pathlib import Path +import bpy from bpy.types import Operator from bpy_extras.asset_utils import ( @@ -72,7 +74,88 @@ class ASSET_OT_tag_remove(Operator): return {'FINISHED'} +class ASSET_OT_open_containing_blend_file(Operator): + """Open the blend file that contains the active asset""" + + bl_idname = "asset.open_containing_blend_file" + bl_label = "Open Blend File" + bl_options = {'REGISTER'} + + _process = None # Optional[subprocess.Popen] + + @classmethod + def poll(cls, context): + asset_file_handle = getattr(context, 'asset_file_handle', None) + asset_library = getattr(context, 'asset_library', None) + + if not asset_library: + cls.poll_message_set("No asset library selected") + return False + if not asset_file_handle: + cls.poll_message_set("No asset selected") + return False + if asset_file_handle.local_id: + cls.poll_message_set("Selected asset is contained in the current file") + return False + return True + + def execute(self, context): + asset_file_handle = context.asset_file_handle + asset_library = context.asset_library + + if asset_file_handle.local_id: + self.report({'WARNING'}, "This asset is stored in the current blend file") + return {'CANCELLED'} + + asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file_handle, asset_library) + self.open_in_new_blender(asset_lib_path) + + wm = context.window_manager + self._timer = wm.event_timer_add(0.1, window=context.window) + wm.modal_handler_add(self) + + return {'RUNNING_MODAL'} + + def modal(self, context, event): + if event.type != 'TIMER': + return {'PASS_THROUGH'} + + if self._process is None: + self.report({'ERROR'}, "Unable to find any running process") + self.cancel(context) + return {'CANCELLED'} + + returncode = self._process.poll() + if returncode is None: + # Process is still running. + return {'RUNNING_MODAL'} + + if returncode: + self.report({'WARNING'}, "Blender subprocess exited with error code %d" % returncode) + + # TODO(Sybren): Replace this with a generic "reload assets" operator + # that can run outside of the Asset Browser context. + if bpy.ops.file.refresh.poll(): + bpy.ops.file.refresh() + if bpy.ops.asset.list_refresh.poll(): + bpy.ops.asset.list_refresh() + + self.cancel(context) + return {'FINISHED'} + + def cancel(self, context): + wm = context.window_manager + wm.event_timer_remove(self._timer) + + def open_in_new_blender(self, filepath): + import subprocess + + cli_args = [bpy.app.binary_path, str(filepath)] + self._process = subprocess.Popen(cli_args) + + classes = ( ASSET_OT_tag_add, ASSET_OT_tag_remove, + ASSET_OT_open_containing_blend_file, ) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 96855cb4a07..8ca93d2406c 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -552,6 +552,10 @@ class FILEBROWSER_MT_context_menu(Menu): sub.operator_context = 'EXEC_DEFAULT' sub.operator("file.delete", text="Delete") + active_asset = asset_utils.SpaceAssetInfo.get_active_asset(context) + if active_asset: + layout.operator("asset.open_containing_blend_file") + layout.separator() sub = layout.row() @@ -613,6 +617,8 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel): row = col.row() row.label(text=asset_lib_path) + row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS') + class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel): bl_label = "Preview" -- cgit v1.2.3 From 87c1c8112fa44ccb94a3e996b7499d6577d85d7f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 13 Jul 2021 15:01:00 +0200 Subject: UI: Support UI list tooltips, defined via Python scripts Makes it possible to create tooltips for UI list rows, which can be filled in .py scripts, similar to how they can extend other menus. This is used by the (to be committed) Pose Library add-on to display pose operations (selecting bones of a pose, blending a pose, etc). It's important that the Python scripts check if the UI list is the correct one by checking the list ID. For this to work, a new `bpy.context.ui_list` can be checked. For example, the Pose Library add-on does the following check: ``` def is_pose_asset_view() -> bool: # Important: Must check context first, or the menu is added for every kind of list. list = getattr(context, "ui_list", None) if not list or list.bl_idname != "UI_UL_asset_view" or list.list_id != "pose_assets": return False if not context.asset_handle: return False return True ``` --- release/scripts/startup/bl_ui/__init__.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index ef705f8fe37..25484e905c3 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -117,13 +117,15 @@ def register(): for cls in mod.classes: register_class(cls) - # space_userprefs.py from bpy.props import ( EnumProperty, StringProperty, ) - from bpy.types import WindowManager + from bpy.types import ( + WindowManager, + ) + # space_userprefs.py def addon_filter_items(_self, _context): import addon_utils @@ -234,3 +236,21 @@ class UI_UL_list(bpy.types.UIList): bpy.utils.register_class(UI_UL_list) + + +class UI_MT_list_item_context_menu(bpy.types.Menu): + """ + UI List item context menu definition. Scripts can append/prepend this to + add own operators to the context menu. They must check context though, so + their items only draw in a valid context and for the correct UI list. + """ + + bl_label = "List Item" + bl_idname = "UI_MT_list_item_context_menu" + + def draw(self, context): + # Dummy function. This type is just for scripts to append their own + # context menu items. + pass + +bpy.utils.register_class(UI_MT_list_item_context_menu) -- cgit v1.2.3