Nodes: Support for input/output sockets in same vertical space #112250
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
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
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 project
No Assignees
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#112250
Loading…
Reference in New Issue
No description provided.
Delete Branch "LukasTonne/blender:node-inline-sockets"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Declarations can use the
add_input_output
method to create a combined input/output socket. The drawing code supports moving sockets up one vertical slot to align them with the predecessor.Closes #112235
Currently this will fail on the socket validation function (correctly!) because the inlined input socket appears before output sockets, which is considered invalid. Either have to relax this condition or add a special flag to exempt these sockets.
Do you think eventually node declarations could be refactored to be stored more like the interface tree items, so that code like this wouldn't be necessary? I'm fine with doing that later, but it seems like this leaves the code in an unnecessarily complicated state.
@ -474,1 +501,4 @@
struct NodeInterfacePanelData {
const nodes::PanelDeclaration *decl_;
bNodePanelState *state_;
Since this is drawing code, it would be nice if these were const pointers. Same below.
I've added some comments to this struct.
state
could potentially be made const, but currently draw code also updates theNODE_PANEL_PARENT_COLLAPSED
flag in there (hiding the panel and its content). This could be done in a separate pass, but that would just duplicate the drawing code loop.The
runtime
data stores transient draw info like the location, so it needs to be mutable.Okay-- I'd like to move that runtime location storage to
SpaceNode
runtime, but while we still reorder nodes based on selection that's too tricky.@ -475,0 +511,4 @@
};
struct NodeInterfaceSocketData {
const nodes::SocketDeclaration *decl_;
These are public members, which shouldn't have the
_
suffix. Same above.@ -475,0 +517,4 @@
operator bool() const
{
/* One socket side is enough to be valid. */
It's not clear what "valid" means here
@ -500,2 +646,2 @@
* the stack. Each panel expects a number of items to be added, after which the panel is removed
* from the stack again. */
* new #PanelUpdate is added to the stack. Items in the declaration are added to the top panel
* of the stack. Each panel expects a number of items to be added, after which the panel is
Unnecessary formatting change?
Bah, clang-format keeps doing this, and it's usually in a multiline comment where it's not immediately obvious ...
make format
insists on this, guess it was wrong before 🤷@ -247,3 +248,3 @@
class BaseSocketDeclarationBuilder {
protected:
int index_ = -1;
int index_in_ = -1;
Seems important to add comments here
That might be nice, but it could also just become more complicated.
The declarations code sits between two different systems:
I want to have a single builder instance returned by
add_input_output
to make declarations intuitive, but it has to generate 2 basic sockets. The node declarations themselves also have to match the sockets 1:1 because of how they are used in various places as supplementary info for sockets. So now 1 builder has to keep track of 2 declarations.Hi Lukas, could you please check what am I doing wrong? Because on my initial tests this is not working for me in two ways:
@dfelinto You are just missing a line to enable the custom layout features:
5dcbc47f0e
toe2313abf3a
@ -457,0 +445,4 @@
/* Context pointers for current node and socket. */
PointerRNA nodeptr = RNA_pointer_create(&ntree.id, &RNA_Node, &node);
PointerRNA sockptr = RNA_pointer_create(&ntree.id, &RNA_NodeSocket, input_socket);
uiLayoutSetContextPointer(row, "node", &nodeptr);
Might as well set the node constext pointer only once above
@ -475,0 +529,4 @@
};
/* Utility to ensure valid state while iterating over interface items and sockets. */
struct NodeInterfaceIterator {
Maybe it's worth mentioning the similarity to
bNodeTreeInterface::foreach_item
here? Or how it's different too maybe?@ -475,0 +530,4 @@
/* Utility to ensure valid state while iterating over interface items and sockets. */
struct NodeInterfaceIterator {
private:
Instead of
struct ... { private:
, this could just beclass ...
@ -475,0 +543,4 @@
NodeInterfaceIterator(bNode &node)
: node_(node),
decl_index_(0),
input_(static_cast<bNodeSocket *>(node.inputs.first)),
Can use
node.inputs()
andnode.outputs()
spans here instead of using the next and prev pointers I think@ -475,0 +528,4 @@
}
};
/* Utility to ensure valid state while iterating over interface items and sockets. */
In my experience it is often easier to just fill a vector with all the elements instead of building an iterator that has to keep track of the current iteration state explicitly. You could just build a
Vector<std::variant<NodeInterfaceSocketData, NodeInterfacePanelData>>
in one go (with some large inline buffer), and then iterate over it afterwards. That also often makes debugging easier, because it's much easier to check that the generated vector contains what you expect.Sounds reasonable, i'll give it a try.
I've replaced the iterator as suggested, hopefully the code is a little bit easier to understand.
@ -273,2 +278,3 @@
static_assert(std::is_base_of_v<SocketDeclaration, SocketDecl>);
SocketDecl *decl_;
SocketDecl *decl_in_;
SocketDecl *decl_out_;
What do you think about also storing a
Vector<SocketDecl *, 2>
here that either contains one or two decls? This could reduce some redundancy in the methods below because one could use a loop instead of repeating the code twice.I've tried this and it doesn't meaningfully reduce the amount of code. There are also a bunch of places where an input declaration is treated differently from an output declaration and would have to check the type, for example (code from
main
):We might eventually have cases where a single declaration builder can generate a whole bunch of sockets, like a multi-input, but i'd rather implement this when needed.
@blender-bot build
@blender-bot build
@blender-bot build
@blender-bot build