imgui-node-editor icon indicating copy to clipboard operation
imgui-node-editor copied to clipboard

Advanced link path layout when it intersects source or target node

Open abvadabra opened this issue 4 years ago • 14 comments
trafficstars

Hi!

This pull request implements improved behaviour for links drawing in cases when drawing it using simple bezier curve would intersect either target or source node. This idea is mainly inspired by implementation of creation graphs in The Machinery engine (reference image, notice behaviour of links between nodes at the very bottom).

In many cases this makes it much easier to keep readiblity while maintaining complex graphs and it's quite a noticeable UX improvement in comparison, with, e.g. UE4's Blueprints.

Demonstration of links difference with, and without this feature: demo_1_1 demo_1_2

Demonstation of link behaviour when node is moved: demo_node_editor

Right now proposed implementation is more like a prototype and not really finalized, I am willing to work on it further if you think that this is appropriate addition for imgui-node-editor.

During implementation I tried to keep code simple and reuse existing functionality as much as possible. The most noticable change is in the way link's curve is represented, instead of four bezier points it's now a struct which contains up to 16 points (NodeEditor::Detail::LinkPath). New types of links will be used only when start pin outputs to the right (with dir 1, 0) and end pin takes input from the left (with dir -1, 0)

If link can be drawn with a simple bezier then only first 4 points will be used and filled with control points for a single curve (just as before). If Link::GetPathType decides that link can intersect source or target node then curve will be constructed from four bezier curves, each describing one corner of the path. During link processing routines (rendering, hit testing, etc) for such cases additional straight line will be derived from each 4nth and 5th point (except for the last pair). These derived straight lines are still interpreted as beziers in order to reuse existing code.

Current known issues/further improvements:

  • I am a little unsure whether this feature should be enabled by default, since in some cases it might be not appropriate. I think we can add style option which controls this behaviour and set it disabled initially.
  • Current implementation of complex curve rendering can produce a bit of a gap between corner beziers and straight lines pieces. I am struggling with fixing it but luckily this gap is not really noticeable unless you zoom really close
  • There are some hidden constants in new path layouting code, which can be exposed via style interface.

abvadabra avatar Aug 25 '21 00:08 abvadabra

looks nice :)

mgood7123 avatar Aug 27 '21 07:08 mgood7123

Hi @abvadabra

Link routing look like a nice idea. Thank you for making a prototype. I will try to take a closer look at your work this weekend and get you a feedback.

This may be a promising introduction to auto-routing. : )

thedmd avatar Aug 27 '21 07:08 thedmd

Was this ever taken into serious consideration? The blueprints reroute pin is definitely something that I miss, and this could be a good workaround in the meantime.

DiegoBM avatar Dec 10 '21 23:12 DiegoBM

I do want to integrate such feature into node editor.

In the mean time, reroute pin can be built from regular node. image Recently I discovered I cannot use same pin as input&output at the same time. So there has to be two pins present, eventually I want add ability to reduce it to pin size node.

thedmd avatar Dec 12 '21 15:12 thedmd

It makes perfect sense, thank you for letting me know about that node, I was not aware of it.

DiegoBM avatar Dec 12 '21 18:12 DiegoBM

@DiegoBM Node is just an interactive rectangle. Custom reroute nodes there are only two pins of same type. You can place anything inside. :)

thedmd avatar Dec 12 '21 21:12 thedmd

is there a time plane when this feature/pull request will make it into the library?

just asking if it makes sense to implement a basic version myself in my fork or wait for it here.

ToppDev avatar Dec 13 '21 06:12 ToppDev

I think it will be a while. You can however cherry-pick abvadabra work and use it as it is now.

thedmd avatar Dec 13 '21 17:12 thedmd

Currently looking into it, but is it possible to make it so a dir of (0,1) or (0,-1) still enables this path?

Stanlyhalo avatar Jan 28 '22 05:01 Stanlyhalo

@Stanlyhalo It is possible, in order to do so you'd have to:

  1. Add desired types of path to the enum ed::LinkPathType.
  2. Implement logic which decides which type of path should be used depending on the relative positioning of two node. This is done in the function ed::Link::GetPathType.
  3. Implement actual path layouting logic in the function ed::Link::GetCurve(). It's implementation for horizontal links may look a bit intimidating at first but you just have to follow the same logic and it will be fine.

I suggest that you first make a mockup of how this kind of link layouting should work with vertical pins, it should be easier once you know what you're trying to achieve.

abvadabra avatar Jan 28 '22 18:01 abvadabra

@abvadabra Just a question, is it the if statement that checks if the type is default that generates the path of the link that you made? image

Stanlyhalo avatar Jan 28 '22 18:01 Stanlyhalo

@Stanlyhalo No, Default type is for simple bezier links, it is the original behaviour which is available without this PR.

abvadabra avatar Jan 28 '22 18:01 abvadabra

Wait I'm confused, than where is it drawn/calculated?

Stanlyhalo avatar Jan 28 '22 18:01 Stanlyhalo