Page MenuHome

UI: Multi-input node socket spacing and interaction
ClosedPublic

Authored by Fabian Schempp (fabian_schempp) on Jan 23 2021, 1:17 AM.

Details

Summary

This patch is based on D10067

Makes links connected to Multi Input Sockets verticaly spread along the socket.
Sockets are growing if more links are connected and Node layout updates accordingly.
Linkes are sorted by angle between fromlink to tolink to avoid crossing links.
link picking is updated to work with spread links and bezier links.


Overview of changes:

  • Adds support for multiple links that are connected to one socket to be drawn with a small gap between
  • Adds support for multiple links that are connected to one socket to be sorted by Y position of the from_node
  • Adds support for links from Multi Input Sockets being picked by a dragging gesture
  • Adds support for links being highlighted while being picked by a dragging gesture

source/blender/editors/space_node/node_relationships.c
source/blender/editors/space_node/drawnode.

  • Adds support for node layout changes according to dynamic socket height of Multi Input Sockets.

source/blender/editors/interface/interface_widgets.c

  • Changes socket drawing from GL_POINTS to GL_TRIANGLES (using new shader)to display long rectangle shape which is not possible with GL_POINTS
  • Changes the way the node layout is calculated to work with growing Multi Input Sockets
  • Adds a constant for highlight color for links that are being highlighted while being picked by dragging gesture.
  • Adds support for links with the flag NODE_LINK_HIGHLIGHT to be drawn with the highlight color.

source/blender/editors/space_node/node_draw.c

  • Adds support for mouse cursor can interact with non square sockets in node_find_indicated_socket()
  • Adds the function node_socket_calculate_height() to calculate socket height.

source/blender/editors/space_node/node_edit.c

  • Adds define for gap between linkes that are connected to Multi Input Sockets NODE_MULTI_INPUT_LINK_GAP */

source/blender/editors/space_node/node_intern.h

  • Adds a new shape flag SOCK_DISPLAY_SHAPE_MULTI
  • Adds a member to bNodeSocket to store total input linkes
  • Adds a member to bNodeLink to store its index on Multi Input Sockets
  • Adds a define for the flag NODE_LINK_HIGHLIGHT that is used to store that a link is highlighted on picking gesture*/

source/blender/makesdna/DNA_node_types.h

source/blender/nodes/intern/node_util.c

  • Make Multi Input Sockets use the new shape id

source/blender/nodes/intern/node_socket.cc

  • Adds a new shader that is used instead of gpu_shader_keyframe_diamond
  • and is capable of drawing the new shape in different heights.

source/blender/gpu/CMakeLists.txt
source/blender/gpu/GPU_shader.h
source/blender/gpu/intern/gpu_shader_builtin.c
source/blender/gpu/shaders/gpu_shader_node_socket_frag.glsl
source/blender/gpu/shaders/gpu_shader_node_socket_vert.glsl

  • Changes that are needed because signiture of node_draw_socket changes

source/blender/editors/include/ED_node.h

Diff Detail

Repository
rB Blender
Branch
geometry_nodes_multi_input_socket_new_drawing (branched from master)
Build Status
Buildable 12676
Build 12676: arc lint + arc unit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Hans Goudey (HooglyBoogly) retitled this revision from Geometry Nodes: Socket Growing and Link Spaceing to UI: Multi-input node socket spacing and interaction.Feb 2 2021, 1:39 AM
Hans Goudey (HooglyBoogly) edited the summary of this revision. (Show Details)
source/blender/editors/space_node/node_draw.c
539

Same comment as somewhere else. It's tempting to do this, but these sort of cleanups should be in a separate commit / patch.

722–738

Why are you deleting all this?

source/blender/editors/space_node/node_edit.c
1156–1162

This can be written a bit more nicely:

const rctf multi_socket_rect = {
    .xmin = sock->locx - NODE_SOCKSIZE * 4,
    .xmax = sock->locx + NODE_SOCKSIZE,
    .ymin = sock->locy - node_socket_calculate_height(sock) * 0.5 -
            NODE_SOCKSIZE * 2.0f,
    .ymax = sock->locy + node_socket_calculate_height(sock) * 0.5 +
            NODE_SOCKSIZE * 2.0f,
};

I also suggest splitting this bit of logic to a separate function named something like:
static bool cursor_isect_multi_input_socket()

source/blender/editors/space_node/node_relationships.c
40

<> -> ""

280

The MUTABLE loops are for when listbase links are removed or freed while iterating. Since this loop doesn't do that, it doesn't need the MUTABLE suffix.

source/blender/makesdna/DNA_node_types.h
176

The other socket display shapes are exposed to RNA in rna_enum_node_socket_display_shape_items.

I'm fine leaving out exposing the new socket shape and drawing from the RNA API for now since this patch set is already pretty large, but it should probably be noted there that this is left out for now.

source/blender/editors/space_node/node_draw.c
762

I would think using the existing UI_draw_roundbox_4fv_ex would be preferable to this.

Fabian Schempp (fabian_schempp) marked 4 inline comments as done.

Changes based on Review by Hans Goudey.

The overall experience is super nice! I've got two comments:

Noodle Color

The hard-coded red-ish tint when unplugging a noodle doesn't feel right. alghough I can't think of an ideal solution right now.

  • White (theme for "active"): Won't work when the node is active, since all noodles connected to it become white too.
  • Orange (theme for "selected"): In Blender it currently means selected. Not wrong but not right either.
  • Red (theme for "alert"): Makes it look like an error (in the near future noodles with errors will become red)

Since soon we are going to have colored wires (based on the socket they come from/connect to) anyway, for the time being I'd just go with orange or theme for "Node Selected".

Expand/contract Behavior

The current "delay" on resizing the socket when a wire is plugged/unplugged, makes it feel not so responsive.

This could be solved by adjusting the size of the socket as soon as the noodle snaps, before releasing/executing the connection. This would solve another issue that happens when the noodle snaps to the same place where there is another noodle currently, suggesting it will replace it (instead of being added below it).

One problem this would introduce though is that we lose that feeling of "ah the node has been executed", but this could be communicated differently (in the compositor for example the node outline is highlighted).


So my suggestions would be to changing the color of the selected wire and resizing the socket on snap, not on release.

Changed link preselection highlighting color to use Theme Selected Color (Orange) based on Review by Pablo Vazquez.

Changed treshhold in shader to make edge a bit more smooth, based on Review by Pablo Vazquez.

@Pablo Vazquez (pablovazquez) Based on your comment in D10080 I changed the new shader to draw the edges of the sockets a bit less crisp. But it's very hard to tell on my monitor if it's really better now. Would be awesome if you could take a look again.

Fixed memoryleak by using BLI_freelinkN instad of BLI_remlink.

Drag Link update Socket and Node layout on snapping.

@Pablo Vazquez (pablovazquez) I made sockets and node update on drag snapping, as you suggested.
That means, that both of your requested changes have been implemented.

---> ATTENTION: I removed the new shader. So you don't have to look into this.

Removed unneeded changes.

Multi Input Sockets now are drawn using UI_draw_roundbox instead of an special shader.

Fabian Schempp (fabian_schempp) marked 2 inline comments as done.Feb 5 2021, 12:15 PM
Charlie Jolly (charlie) added inline comments.
source/blender/makesdna/DNA_node_types.h
176

Minor comment but MULTI isn't a display shape. I don't think SOCK_DISPLAY_SHAPE_MULTI is needed and just document that changing the shape is not supported for MULTI sockets. In future, a MULTI socket may have square or diamond shape for example.

Removed SOCK_DISPLAY_SHAPE_MULTI form shapes enum, based on comment form Charlie Jolly.

Fabian Schempp (fabian_schempp) marked 2 inline comments as done.Feb 5 2021, 9:19 PM
Hans Goudey (HooglyBoogly) requested changes to this revision.Feb 10 2021, 1:42 AM

I have a case of crossing node links:

The rest of the comments are inline. I think this will end up being the last or second-to-last review pass.

source/blender/editors/space_node/node_draw.c
505

Just make this a float, it's only used as one

506–511

This can be written more simply:

if (nsock->flag & SOCK_MULTI_INPUT) {
  if (nsock->total_inputs > 2) {
    multi_input_socket_offset = (nsock->total_inputs - 2) * NODE_MULTI_INPUT_LINK_GAP;
  }
}

Also, at first I thought this code was to make the label start half-way down the bar, but this actually just accounts for the size of the socket.
This is not obvious, there should be some brief comment describing this.

512

Values for floats should have an f at the end, like 0.5f, or 0.0f

772

const

773

so wie must compensate for the outline width. -> so compensate for the outline width.

1115

Unnecessary white-space change.

1162

Sure, that's obvious. The comments should explain why, not what.

1673

No need to abbreviate: tmp -> temporary

1696

struct is unecessary

1779–1782

BLI_addtail(&multi_input_socket_links, MEM_dupallocN(linkdata)); should work here, like above.

1799–1800

I'm going to suggest changing this block of code a fair amount. To my eyes it's much more complex than it needs to be:

Here's my suggestion. Much simpler and requires much fewer memory allocations.

LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
  LISTBASE_FOREACH (struct bNodeSocket *, sock, &node->inputs) {
    if (sock->flag & SOCK_MULTI_INPUT) {
      /* This is calculated in #node_update_nodetree, which runs before the draw step. */
      const int total_inputs = sock->total_inputs;

      bNodeLink **input_links = MEM_malloc_arrayN(total_inputs, sizeof(bNodeLink *), __func__);

      int index = 0;
      LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
        if (link->tosock == sock) {
          input_links[index] = (bNodeLink *)link;
          index++;
        }
      }
      LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
        LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
          bNodeLink *link = (bNodeLink *)linkdata->data;
          if (link->tosock == sock) {
            input_links[index] = (bNodeLink *)link;
            index++;
          }
        }
      }

      qsort(input_links, total_inputs, sizeof(bNodeLink *), cmp_link_by_angle_to_node);
      for (int i = 0; i < total_inputs; i++) {
        input_links[i]->multi_input_socket_index = i;
      }

      MEM_freeN(input_links);
    }
  }
}

This also requires a change to the comparison function, it should start with

const bNodeLink *link_a = *(const bNodeLink **)a;
const bNodeLink *link_b = *(const bNodeLink **)b;
source/blender/editors/space_node/node_edit.c
1126

Just put the function up here, no need for a prototype.

1126

const float cursor[2]

1196

Calculate the height above once, then assign it here.

source/blender/editors/space_node/node_relationships.c
29

Also not necessary to include this, at least it compiled for me without it.

42–50

Yes, it compiles, so it's a valid cleanup, but I don't see why you're removing the two of these here.

45

Not necessary anymore.

184

It's surprising to me that this has to be called in so many places. I think you could get away with removing a call to this in a couple places.

Also, the argument is too high-level, I would make the argument a ListBase of links probably.

187

I've mentioned this a few times by now, if the loop doesn't remove or add a link, the _MUTABLE suffix is not needed.
If my comments don't make sense, please ask. Otherwise I'd generally expect you to apply them more generally than just the specific line I commented on.

192

This function is mostly a duplicate of the code near line 900. I only looked at it briefly, but do you think should be shared?

205

calloc already sets this to NULL, no need to clear it. I know this is copied code.

246

Maybe use NODE_LINK_RESOL instead of a separate define.

276

How does this change the behavior? I turned it off and didn't notice difference.

837

Unrelated white-space change

903

Unrelated white-space change

1099

Watch your merge conflicts next time, this was removed in rBfec6a4e24ad3: Cleanup: don't end description with dot

source/blender/makesdna/DNA_node_types.h
147

Use the previous padding bytes earlier in the struct.

Also, this should have a comment: /* Runtime-only cache of the number of input links, for multi-input sockets. */, or something like that.

Also, to enforce the "runtime only" idea, this can be explicitly cleared in direct_link_node_socket.

396

Should have a comment like I mentioned for total_inputs

Something like:
`/* A runtime storage for automatically sorted links to multi-input sockets. */

This revision now requires changes to proceed.Feb 10 2021, 1:42 AM
Fabian Schempp (fabian_schempp) marked 26 inline comments as done.

Changes based on Review by Hans Goudey.

Fabian Schempp (fabian_schempp) added inline comments.
source/blender/editors/space_node/node_relationships.c
184

It's surprising to me that this has to be called in so many places. I think you could get away with removing a call to this in a couple places.

Also, the argument is too high-level, I would make the argument a ListBase of links probably.

187

I've mentioned this a few times by now, if the loop doesn't remove or add a link, the _MUTABLE suffix is not needed.
If my comments don't make sense, please ask. Otherwise I'd generally expect you to apply them more generally than just the specific line I commented on.

Sorry, I assume that this is not a new change otherwise I would have known by now.

276

It is possible that you drag and while you are dragging, into the right direction, your cursor leaves the intersection with the link you picked, which results in not picking the link. I found that this can feel a bit wired.

This looks pretty good to me. I'm tweaking some things and doing some cleanup, but I'll commit in a few minutes.

This revision is now accepted and ready to land.Feb 11 2021, 7:14 AM

Done! Thanks again for working on this Fabian, I think the results are so awesome.

To see what I tweaked in the committed version you can select the diff between your last update and the commit here: