Nodes: port "Lazy Connect" feature from Node Wrangler #122428

Open
Nika Kutsniashvili wants to merge 7 commits from nickberckley/blender:lazy-connect into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
Contributor

Second PR for porting core functionalities of Node Wrangler add-on into Blender. For reasons and design see #121749

This ports Lazy Connect feature. Hovering over the node and alt-right-clicking draws grey box around the node and link, which can be connected to second node to make quick connection. Feature has two modes:

  1. Automatic connection (alt-RMB): operator automatically starts connecting first unused output socket to input socket that best matches it (based on its type). Works great most of the time, especially for nodes with few inputs/outputs.

  1. Link From/To (shift-alt-RMB): When making a connection and releasing a mouse it shows you two menus in succession, in first you choose output socket of first node, and in second you choose input socket of second node. If either of those nodes only has one input or output menu is skipped.


Changes made from Node Wrangler version:

  • In order to function operator needs to register properties that need to be available outside of operator context. Add-on was registering those properties on scene, which didn't make sense, because (a) those are temporary properties which don't need to exist outside runtime data, and (b) those properties are useless for user and shouldn't be exposed in Custom Properties panel in Scene Properties category and clutter it. So I registered those properties on window_manager, where it makes more sense.

To decide:

  • When making automatic connection boxes and link are drawn as red. Red is associated with invalid link in node editors and this one doesn't fit into that design. Maybe green would be better choice? (If I remember correctly green is used in Node Wrangler for some other operator, but I can change that).

After this PR is merged this feature will be removed from Node Wrangler extension (which is hosted here), so that it doesn't implement what is already part of Blender.

Original authors of the add-on: Bartek Skorupa, Greg Zaal, Sebastian Koenig, Christian Brinkmann, Florian Meyer

Second PR for porting core functionalities of Node Wrangler add-on into Blender. For reasons and design see #121749 This ports Lazy Connect feature. Hovering over the node and alt-right-clicking draws grey box around the node and link, which can be connected to second node to make quick connection. Feature has two modes: 1. Automatic connection (alt-RMB): operator automatically starts connecting first unused output socket to input socket that best matches it (based on its type). Works great most of the time, especially for nodes with few inputs/outputs. <video src="/attachments/c7d1f92c-7ade-4005-bebc-f68d9835ff73" title="2024-05-29 13-13-41.mkv" controls></video> 2. Link From/To (shift-alt-RMB): When making a connection and releasing a mouse it shows you two menus in succession, in first you choose output socket of first node, and in second you choose input socket of second node. If either of those nodes only has one input or output menu is skipped. <video src="/attachments/60d29f28-6161-4ea6-beec-cbaa3471501e" title="2024-05-29 13-13-49.mkv" controls></video> --- Changes made from Node Wrangler version: - In order to function operator needs to register properties that need to be available outside of operator context. Add-on was registering those properties on scene, which didn't make sense, because (a) those are temporary properties which don't need to exist outside runtime data, and (b) those properties are useless for user and shouldn't be exposed in Custom Properties panel in Scene Properties category and clutter it. So I registered those properties on window_manager, where it makes more sense. To decide: - When making automatic connection boxes and link are drawn as red. Red is associated with invalid link in node editors and this one doesn't fit into that design. Maybe green would be better choice? (If I remember correctly green is used in Node Wrangler for some other operator, but I can change that). --- After this PR is merged this feature will be removed from Node Wrangler extension (which is hosted here), so that it doesn't implement what is already part of Blender. Original authors of the add-on: Bartek Skorupa, Greg Zaal, Sebastian Koenig, Christian Brinkmann, Florian Meyer
Nika Kutsniashvili added 1 commit 2024-05-29 11:17:13 +02:00
Nika Kutsniashvili added 1 commit 2024-05-29 11:18:01 +02:00
Nika Kutsniashvili requested review from Jacques Lucke 2024-05-29 11:18:55 +02:00
Iliya Katushenock added this to the Nodes & Physics project 2024-05-29 11:19:56 +02:00
Member

I don't quite understand why this needs to store properties on the window manager. Shouldn't it be possible to store those on the operator directly?

[Edit] Ah, probably because you want to pass them to the menu. I kind of remember that this was possible in a different way, but don't know how exactly. I think I'd prefer to store them as global values in Python, instead of adding them to the window manager.

I don't quite understand why this needs to store properties on the window manager. Shouldn't it be possible to store those on the operator directly? [Edit] Ah, probably because you want to pass them to the menu. I kind of remember that this was possible in a different way, but don't know how exactly. I think I'd prefer to store them as global values in Python, instead of adding them to the window manager.
Author
Contributor

@JacquesLucke there's a chain of operators that call each other and each of them need to know nodes which they're working on. And there is no way to transfer operator property from one operator to another.

Chain of operators is needed in order to draw two menus (From, To) in succession.

@JacquesLucke there's a chain of operators that call each other and each of them need to know nodes which they're working on. And there is no way to transfer operator property from one operator to another. Chain of operators is needed in order to draw two menus (From, To) in succession.
Member

See my updated comment above.

One major concern here is the use of colors, many different colors actually. I wonder if there is any specific reasoning behind the used colors or whether it's ok to just use a more neutral color for all highlighted nodes, regardless of the operator. That's also something for the UI Team to decide.

See my updated comment above. One major concern here is the use of colors, many different colors actually. I wonder if there is any specific reasoning behind the used colors or whether it's ok to just use a more neutral color for all highlighted nodes, regardless of the operator. That's also something for the UI Team to decide.
Brecht Van Lommel reviewed 2024-05-29 16:02:26 +02:00
@ -1,8 +1,11 @@
# SPDX-FileCopyrightText: 2024 Blender Authors
# SPDX-FileCopyrightText: 2024 Blender Foundation

The copyright should be Blender Authors for all these files, not Blender Foundation.

The copyright should be `Blender Authors` for all these files, not `Blender Foundation`.
nickberckley marked this conversation as resolved
Author
Contributor

I think in order for global values to work I need to define lot more inside the lazy_connect.py file than I do now. I won't be able to extract functions in outside files. I wanted them in separate files so that Lazy Mix could also import them in separate file, but if I do global values I'll have to port Lazy Mix in the same file as Lazy Connect, is that ok?

I think in order for global values to work I need to define lot more inside the lazy_connect.py file than I do now. I won't be able to extract functions in outside files. I wanted them in separate files so that Lazy Mix could also import them in separate file, but if I do global values I'll have to port Lazy Mix in the same file as Lazy Connect, is that ok?
Member

I think in order for global values to work I need to define lot more inside the lazy_connect.py file than I do now.

What's a "lot" here? Doesn't seem like this would require more code. What extra code would it need in your opinion?

Also I kind of think that these properties shouldn't be shared between different operators if it can be avoided. They could be static properties on the operator classes. The only place where I see the global properties used outside of lazy_connect.py right now is in draw_callback_node_outline. Arguably, it would be better to define that as a standalone function that all relevant data is passed into more explicitly.

> I think in order for global values to work I need to define lot more inside the lazy_connect.py file than I do now. What's a "lot" here? Doesn't seem like this would require more code. What extra code would it need in your opinion? Also I kind of think that these properties shouldn't be shared between different operators if it can be avoided. They could be static properties on the operator classes. The only place where I see the global properties used outside of `lazy_connect.py` right now is in `draw_callback_node_outline`. Arguably, it would be better to define that as a standalone function that all relevant data is passed into more explicitly.
Author
Contributor

@JacquesLucke I tried passing nodes as arguments inside draw_callback_node_outline, but it's not working. I think global values aren't defined at that point when it's called. It's working if I import drawing code inside the lazy_connect.py file and let it access global values. Is that alright?

@JacquesLucke I tried passing nodes as arguments inside `draw_callback_node_outline`, but it's not working. I think global values aren't defined at that point when it's called. It's working if I import drawing code inside the lazy_connect.py file and let it access global values. Is that alright?
Member

Sorry, I'm not sure what's the problem with global values here. Can you be more specific with what you tried and why it didn't work?

Sorry, I'm not sure what's the problem with global values here. Can you be more specific with what you tried and why it didn't work?
Author
Contributor

@JacquesLucke inside the invoke of the operator I'm not able to access source and target global values. It returns none, and in order to pass nodes as arguments to draw_callback_node_outline I need to get them there. During invoke they're not given any value yet by the operator.

When draw_callback_node_outline accesses those global values inside itself it's able to get them, because by that time execute already gave them values

@JacquesLucke inside the invoke of the operator I'm not able to access source and target global values. It returns none, and in order to pass nodes as arguments to `draw_callback_node_outline` I need to get them there. During invoke they're not given any value yet by the operator. When draw_callback_node_outline accesses those global values inside itself it's able to get them, because by that time `execute` already gave them values
Member

Here is an example for demonstration purposes: fb59201dd1

Just noticed that the nodes_lazy_drawing property is quite weird. Sometimes it's a node name, sometimes STOP.

Here is an example for demonstration purposes: https://projects.blender.org/JacquesLucke/blender/commit/fb59201dd18cc4aed7dc3a5a445528d0eb270683 Just noticed that the `nodes_lazy_drawing` property is quite weird. Sometimes it's a node name, sometimes `STOP`.
Nika Kutsniashvili added 1 commit 2024-05-29 17:34:07 +02:00
Author
Contributor

@JacquesLucke thanks once again for helping.

I removed check for 'STOP' string. It was indeed weird. I couldn't find anything in commit history, but I'm assuming at one point operator explicitly set the value as 'STOP' but doesn't anymore. It works fine without it.

@JacquesLucke thanks once again for helping. I removed check for 'STOP' string. It was indeed weird. I couldn't find anything in commit history, but I'm assuming at one point operator explicitly set the value as 'STOP' but doesn't anymore. It works fine without it.
Jacques Lucke requested changes 2024-05-31 13:12:51 +02:00
@ -0,0 +22,4 @@
@dataclass
class LazyConnectProperties:
nodes_lazy_drawing: str = ""
Member

I think these names could be improved now. I don't quite understand what the name means tbh.
The ones below could just be from_node_name, to_node_name, etc.

I think these names could be improved now. I don't quite understand what the name means tbh. The ones below could just be `from_node_name`, `to_node_name`, etc.
nickberckley marked this conversation as resolved
@ -0,0 +31,4 @@
class NODE_MT_lazy_connect_outputs(Menu, NodeEditorMenuBase):
bl_idname = "NODE_MT_lazy_connect_outputs"
Member

Make consistent use of " vs ' and _MT_ vs .

Make consistent use of `" vs '` and `_MT_ vs .`
Author
Contributor

I'm not sure I fully understand _MT_ vs . but I think its standard in Blender to reuse class name for bl_idname for menus, every menu in 3D viewport headers does that.

I'm not sure I fully understand `_MT_ vs .` but I think its standard in Blender to reuse class name for bl_idname for menus, every menu in 3D viewport headers does that.
@ -0,0 +73,4 @@
bl_label = 'Make Link'
bl_options = {'REGISTER', 'UNDO'}
from_socket: IntProperty(
Member

This formatting looks a bit weird. Same below.

This formatting looks a bit weird. Same below.
nickberckley marked this conversation as resolved
@ -0,0 +211,4 @@
# Add the region OpenGL drawing callback.
# Draw in view space with 'POST_VIEW' and 'PRE_VIEW'.
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(
lambda self, context, mode: draw_callback_node_outline(self, context, mode, lazy_connect_props), args, 'WINDOW', 'POST_PIXEL')
Member

Just noticed that the lambda should be able to capture self/context/mode automatically, so args shouldn't be necessary maybe?

Just noticed that the `lambda` should be able to capture `self/context/mode` automatically, so `args` shouldn't be necessary maybe?
Author
Contributor

I tried it but Space.draw_handler_add always expects 5 arguments and removing args breaks it. I think lambda only passes (self, context, mode) to draw_callback_node_outline and not to draw_handler_add

I tried it but Space.draw_handler_add always expects 5 arguments and removing args breaks it. I think lambda only passes (self, context, mode) to `draw_callback_node_outline` and not to `draw_handler_add`
Member

Can’t you just do

@@ -199,18 +199,18 @@ class NODE_OT_lazy_connect(Operator, NodeEditorBase):
             if node:
                 lazy_connect_props.node_below_drawing_name = node.name
 
+            self.mouse_path = []
+
             # The arguments we pass the the callback.
             mode = "LINK"
             if self.with_menu:
                 mode = "LINKMENU"
-            args = (self, context, mode)
+            args = (context, self.mouse_path, mode, lazy_connect_props)
 
             # Add the region OpenGL drawing callback.
             # Draw in view space with 'POST_VIEW' and 'PRE_VIEW'.
             self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(
-                lambda self, context, mode: draw_callback_node_outline(context, self.mouse_path, mode, lazy_connect_props), args, 'WINDOW', 'POST_PIXEL')
-
-            self.mouse_path = []
+                draw_callback_node_outline, args, 'WINDOW', 'POST_PIXEL')
 
             context.window_manager.modal_handler_add(self)
             return {'RUNNING_MODAL'}

?

Can’t you just do ```diff @@ -199,18 +199,18 @@ class NODE_OT_lazy_connect(Operator, NodeEditorBase): if node: lazy_connect_props.node_below_drawing_name = node.name + self.mouse_path = [] + # The arguments we pass the the callback. mode = "LINK" if self.with_menu: mode = "LINKMENU" - args = (self, context, mode) + args = (context, self.mouse_path, mode, lazy_connect_props) # Add the region OpenGL drawing callback. # Draw in view space with 'POST_VIEW' and 'PRE_VIEW'. self._handle = bpy.types.SpaceNodeEditor.draw_handler_add( - lambda self, context, mode: draw_callback_node_outline(context, self.mouse_path, mode, lazy_connect_props), args, 'WINDOW', 'POST_PIXEL') - - self.mouse_path = [] + draw_callback_node_outline, args, 'WINDOW', 'POST_PIXEL') context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} ``` ?
Author
Contributor

If I don't use lambda I can yes. If Jacque is ok with that I prefer that way as well

If I don't use lambda I can yes. If Jacque is ok with that I prefer that way as well
@ -0,0 +12,4 @@
)
def draw_line(x1, y1, x2, y2, size, colour=(1.0, 1.0, 1.0, 0.7)):
Member

colour -> color everywhere

`colour` -> `color` everywhere
nickberckley marked this conversation as resolved
@ -0,0 +171,4 @@
def draw_callback_node_outline(self, context, mode, lazy_connect_props):
if self.mouse_path:
Member

Better pass in mouse_path instead of self.
Also it's generally better to return early if mouse_path is None/empty, instead of indenting the code.

Better pass in `mouse_path` instead of `self`. Also it's generally better to return early if `mouse_path` is `None/empty`, instead of indenting the code.
nickberckley marked this conversation as resolved
@ -94,0 +110,4 @@
space = context.space_data
tree = space.edit_tree
# convert mouse position to the View2D for later node placement
Member

Fix comment style in this file.

Fix comment style in this file.
nickberckley marked this conversation as resolved
Nika Kutsniashvili added 1 commit 2024-05-31 14:13:24 +02:00
Damien Picard reviewed 2024-06-02 14:51:46 +02:00
Damien Picard left a comment
Member
  • There is a keymap conflict with node.select assigned to Alt + RMB and Shift + Alt + RMB, I think they should be removed.

  • The operator, keymap and utils for Lazy Connect should be removed from addons_core/nodewrangler in this PR.

- There is a keymap conflict with `node.select` assigned to Alt + RMB and Shift + Alt + RMB, I think they should be removed. - The operator, keymap and utils for Lazy Connect should be removed from addons_core/nodewrangler in this PR.
@ -0,0 +71,4 @@
"""Link from this output"""
bl_idname = "node.call_inputs_menu"
bl_label = "Make Link"
bl_options = {'REGISTER', 'UNDO'}
Member

This line can be deleted as there is no need to add an undo event, it’s already added by the LazyConnect operator.

This line can be deleted as there is no need to add an undo event, it’s already added by the LazyConnect operator.
nickberckley marked this conversation as resolved
@ -0,0 +93,4 @@
"""Make a link from one socket to another"""
bl_idname = "node.make_link"
bl_label = "Make Link"
bl_options = {'REGISTER', 'UNDO'}
Member

This line can be deleted as there is no need to add an undo event, it’s already added by the LazyConnect operator.

This line can be deleted as there is no need to add an undo event, it’s already added by the LazyConnect operator.
nickberckley marked this conversation as resolved
@ -0,0 +111,4 @@
return {'FINISHED'}
class NODE_OT_lazy_connect(Operator, NodeEditorBase):
Member

No need for the NodeEditorBase mixin if the poll method is overridden. (Or the poll override can be removed.)

No need for the NodeEditorBase mixin if the poll method is overridden. (Or the poll override can be removed.)
nickberckley marked this conversation as resolved
@ -0,0 +156,4 @@
link_success = False
if cont:
if node1 and node2:
Member
if cont:
    if node1 and node2:

is the same as :

if cont and node1 and node2:
```python if cont: if node1 and node2: ``` is the same as : ```python if cont and node1 and node2: ```
nickberckley marked this conversation as resolved
@ -0,0 +193,4 @@
return {'RUNNING_MODAL'}
def invoke(self, context, event):
if context.area.type == 'NODE_EDITOR':
Member

This is already handled by the poll method.

This is already handled by the poll method.
nickberckley marked this conversation as resolved
@ -0,0 +199,4 @@
if node:
lazy_connect_props.node_below_drawing_name = node.name
# The arguments we pass the the callback.
Member

"the the"

"the the"
nickberckley marked this conversation as resolved
@ -94,0 +128,4 @@
# Will be sorted to find nearest point and thus nearest node.
node_points_with_dist = []
for node in nodes:
skipnode = False
Member

skipnode is always False, can be removed.

`skipnode` is always `False`, can be removed.
nickberckley marked this conversation as resolved
@ -94,0 +130,4 @@
for node in nodes:
skipnode = False
# No point trying to link to a frame node.
if node.type != 'FRAME':
Member
if node.type == 'FRAME':
    continue
```python if node.type == 'FRAME': continue ```
nickberckley marked this conversation as resolved
@ -94,0 +135,4 @@
dimy = node.dimensions.y / dpi_fac()
locx, locy = abs_node_location(node)
if not skipnode:
Member

skipnode is always False.

`skipnode` is always `False`.
nickberckley marked this conversation as resolved
@ -94,0 +157,4 @@
nearest_node = sorted(node_points_with_dist, key=lambda k: k[1])[0][0]
for node in nodes:
if node.type != 'FRAME' and skipnode == False:
Member
if node.type == 'FRAME':
    continue

skipnode is always False.

```python if node.type == 'FRAME': continue ``` `skipnode` is always `False`.
nickberckley marked this conversation as resolved
Nika Kutsniashvili added 1 commit 2024-06-03 19:04:11 +02:00
Author
Contributor

Thanks for clean-up pass @pioverfour

Keymap conflict I can't see, node.select is assigned to LMB buttons, on RMB I can't find anything either in blender_default file or in Blender preferences.

I'll port code for removing this feature from add-on repo into this PR

Thanks for clean-up pass @pioverfour Keymap conflict I can't see, node.select is assigned to LMB buttons, on RMB I can't find anything either in blender_default file or in Blender preferences. I'll port code for removing this feature from add-on repo into this PR
Nika Kutsniashvili added 2 commits 2024-06-03 19:14:36 +02:00
Member

Thanks for clean-up pass @pioverfour

It’s mostly stuff I should have seen when I refactored the operator a few months ago, but didn’t! Thanks for the changes :)

Keymap conflict I can't see, node.select is assigned to LMB buttons, on RMB I can't find anything either in blender_default file or in Blender preferences.

Ahh, that’s because I use right-click select… I don’t know if such tweaks are OK but this fixes it:

modified   scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5240,17 +5240,21 @@ def _template_node_select(*, type, value, select_passthrough):
         ("node.select", {"type": type, "value": value},
          {"properties": [("deselect_all", True), ("select_passthrough", select_passthrough)]}),
         ("node.select", {"type": type, "value": value, "ctrl": True}, None),
-        ("node.select", {"type": type, "value": value, "alt": True}, None),
         ("node.select", {"type": type, "value": value, "ctrl": True, "alt": True}, None),
         ("node.select", {"type": type, "value": value, "shift": True},
          {"properties": [("toggle", True)]}),
         ("node.select", {"type": type, "value": value, "shift": True, "ctrl": True},
          {"properties": [("toggle", True)]}),
-        ("node.select", {"type": type, "value": value, "shift": True, "alt": True},
-         {"properties": [("toggle", True)]}),
         ("node.select", {"type": type, "value": value, "shift": True, "ctrl": True, "alt": True},
          {"properties": [("toggle", True)]}),
     ]
+    if type == 'LEFTMOUSE':
+        # Avoid conflict with node.lazy_connect, which uses these shortcuts in RMB-select.
+        items.extend([
+            ("node.select", {"type": type, "value": value, "alt": True}, None),
+            ("node.select", {"type": type, "value": value, "shift": True, "alt": True},
+             {"properties": [("toggle", True)]}),
+        ])
 
     if select_passthrough and (value == 'PRESS'):
         # Add an additional click item to de-select all other items,

I'll port code for removing this feature from add-on repo into this PR

Thanks!

> Thanks for clean-up pass @pioverfour It’s mostly stuff I should have seen when I refactored the operator a few months ago, but didn’t! Thanks for the changes :) > Keymap conflict I can't see, node.select is assigned to LMB buttons, on RMB I can't find anything either in blender_default file or in Blender preferences. Ahh, that’s because I use right-click select… I don’t know if such tweaks are OK but this fixes it: ```diff modified scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5240,17 +5240,21 @@ def _template_node_select(*, type, value, select_passthrough): ("node.select", {"type": type, "value": value}, {"properties": [("deselect_all", True), ("select_passthrough", select_passthrough)]}), ("node.select", {"type": type, "value": value, "ctrl": True}, None), - ("node.select", {"type": type, "value": value, "alt": True}, None), ("node.select", {"type": type, "value": value, "ctrl": True, "alt": True}, None), ("node.select", {"type": type, "value": value, "shift": True}, {"properties": [("toggle", True)]}), ("node.select", {"type": type, "value": value, "shift": True, "ctrl": True}, {"properties": [("toggle", True)]}), - ("node.select", {"type": type, "value": value, "shift": True, "alt": True}, - {"properties": [("toggle", True)]}), ("node.select", {"type": type, "value": value, "shift": True, "ctrl": True, "alt": True}, {"properties": [("toggle", True)]}), ] + if type == 'LEFTMOUSE': + # Avoid conflict with node.lazy_connect, which uses these shortcuts in RMB-select. + items.extend([ + ("node.select", {"type": type, "value": value, "alt": True}, None), + ("node.select", {"type": type, "value": value, "shift": True, "alt": True}, + {"properties": [("toggle", True)]}), + ]) if select_passthrough and (value == 'PRESS'): # Add an additional click item to de-select all other items, ``` > I'll port code for removing this feature from add-on repo into this PR Thanks!
This pull request has changes conflicting with the target branch.
  • scripts/addons_core/node_wrangler/interface.py
  • scripts/startup/bl_operators/node_editor/node_functions.py

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u lazy-connect:nickberckley-lazy-connect
git checkout nickberckley-lazy-connect
Sign in to join this conversation.
No reviewers
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#122428
No description provided.