Advanced link path layout when it intersects source or target node - #119
Advanced link path layout when it intersects source or target node#119abvadabra wants to merge 6 commits into
Conversation
…k would pass through either source or target node.
|
looks nice :) |
|
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. : ) |
|
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. |
|
It makes perfect sense, thank you for letting me know about that node, I was not aware of it. |
|
@DiegoBM Node is just an interactive rectangle. Custom reroute nodes there are only two pins of same type. You can place anything inside. :) |
|
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. |
|
I think it will be a while. |
|
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 It is possible, in order to do so you'd have to:
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 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? |
|
@Stanlyhalo No, Default type is for simple bezier links, it is the original behaviour which is available without this PR. |
|
Wait I'm confused, than where is it drawn/calculated? |
… path layouting for cases when link would pass through either source or target node. This is a squashed version of thedmd#119
… path layouting for cases when link would pass through either source or target node. This is a squashed version of thedmd#119
|
I created a squashed version of this PR that solves conflicts as of May 2024: pthom@436b296 I like it a lot, thanks a bunch @abvadabra ! PS: this squashed commit is still signed by you |
… path layouting for cases when link would pass through either source or target node. This is a squashed version of thedmd#119
Extend PR thedmd#119's rerouting so it also activates when pins are oriented vertically (output dir (0,+1), input dir (0,-1)). Adds three new path types mirroring the horizontal ones via coordinate transpose: - LinkPathType_Right_Left (target is up-right of source) - LinkPathType_Left_Right (target is up-left of source) - LinkPathType_Right_Right (target overlaps in X, route right) GetPathType now branches on pin direction; GetCurve emits the matching four-corner bezier chain. Horizontal behavior is unchanged.
Extend PR thedmd#119's rerouting so it also activates when pins are oriented vertically (output dir (0,+1), input dir (0,-1)). Adds three new path types mirroring the horizontal ones via coordinate transpose: - LinkPathType_Right_Left (target is up-right of source) - LinkPathType_Left_Right (target is up-left of source) - LinkPathType_Right_Right (target overlaps in X, route right) GetPathType now branches on pin direction; GetCurve emits the matching four-corner bezier chain. Horizontal behavior is unchanged.
Routes links around the source and target nodes instead of drawing straight through them (thedmd#119). Six commits, +304/-48 across imgui_node_editor.cpp and imgui_node_editor_internal.h. The PR is branched from a 2020 commit, so it had drifted roughly six years out of date and would not merge. Only one hunk actually conflicted, in Link::Draw. GetCurve() now returns LinkPath, a multi-segment path (m_Points[16], m_NumPoint) rather than a single ImCubicBezierPoints, and the PR rewrote Draw to loop over segments in steps of four, putting arrowheads only on the first and last. That loop, however, calls the older ImDrawList_AddBezierWithArrows signature and so drops startDirHint and endDirHint -- the m_SnapLinkToDir feature upstream added after the PR was written. Resolved by keeping the PR's loop and threading the hints through it, gated on isStart/isEnd exactly as the arrowheads already are: direction snapping only applies where the path actually meets a pin. Intermediate connector segments touch no pin and pass neither arrowheads nor hints. Taking either side wholesale would have lost something -- ours drops the routing, theirs drops link direction snapping on every routed link. The remaining GetCurve callers -- TestHit, the rect intersection test, GetBounds and the flow path builder -- were all updated by the PR itself to walk every segment, and were checked rather than assumed: a caller that only inspected the first four points would still compile while silently ignoring routed geometry.


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:


Demonstation of link behaviour when node is moved:

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::GetPathTypedecides 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: