Add lasso selection to node graph#3333
Add lasso selection to node graph#3333wade-cheng wants to merge 10 commits intoGraphiteEditor:masterfrom
Conversation
4059fde to
9e255fa
Compare
|
I should say while this is on my mind right now, performance should probably be looked at for this PR. We convert the entire vec of polygon points from one unit to another once every frame. |
0HyperCube
left a comment
There was a problem hiding this comment.
Thanks for your work on this. It seems to work nicely.
It is good to hear you thinking about the performance. However current architectural decisions unfortunately means an excessive number of allocations are necessary.
| /// plus a flag indicating if it has been dragged since the mousedown began. | ||
| lasso_selection_curr: Option<(Vec<DVec2>, bool)>, |
There was a problem hiding this comment.
nit: It is probably clearer to make a struct { lasoo_points: Vec<DVec2>, has_dragged: bool } rather than relying on the doc comment to name the fields. However I suppose the current implementation is consistent with the box selection.
I wonder if it is even necessary to store the has_dragged bool. Can't you just check if the number of points is ≥ 2?
There was a problem hiding this comment.
Re: paragraph 2. Good point, pretty sure that's all the functionality that the dragged bool is used for in the box selection logic anyways.
There was a problem hiding this comment.
Hm. Perhaps the has_dragged field helps make it explicit that we do something related to whether we have moved from the initial mousedown or not. But I agree with removing it.
Also, I took a look, and the only reason box selection can't do without the field either is because we want to update_node_graph_hints only after moving from the initial mousedown. That is, if the initial mousedown was to update the hints, we could remove the field. But for the analogous lasso logic, we just check if the length is at least two, again.
| let lasso_selection_viewport: Vec<DVec2> = lasso_selection_curr | ||
| .iter() | ||
| .map(|selection_point| network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.transform_point2(*selection_point)) | ||
| .collect(); |
There was a problem hiding this comment.
There is no need to call .collect() since you use into_iter() later. You might have to move the frontend message to here though if the borrow checker is unhappy.
There was a problem hiding this comment.
The borrow checker indeed was. And yes, moving the frontend message there fixes it.
| // WARNING WARNING WARNING: this commented-out code is copy pasted from UpdateBoxSelection above and has not been edited for lasso | ||
| // The mouse button was released but we missed the pointer up event | ||
| // if ((e.buttons & 1) === 0) { | ||
| // completeBoxSelection(); | ||
| // boxSelection = undefined; | ||
| // } else if ((e.buttons & 2) !== 0) { | ||
| // editor.handle.selectNodes(new BigUint64Array(previousSelection)); | ||
| // boxSelection = undefined; | ||
| // } | ||
|
|
There was a problem hiding this comment.
What is this relating to? It looks like javascript.
There was a problem hiding this comment.
Oh neat, that is javascript for some reason. Yeah, the identical comment appears in UpdateBoxSelection, and got copied over when I copy-pasted the entire UpdateBoxSelection block. Didn't know if it was important so I left it.
To answer the question more explicitly, don't really know what this relates to, but your guess would be better than mine anyhow.
There was a problem hiding this comment.
The box selection seems to be working fine for many months, so it is probably safe to delete this comment (in both places).
| let node_graph_point = network_metadata | ||
| .persistent_metadata | ||
| .navigation_metadata | ||
| .node_graph_to_viewport |
There was a problem hiding this comment.
nit: Probably less verbose to let node_graph_to_viewport = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport;
| if nodes != previous_selection { | ||
| responses.add(NodeGraphMessage::SelectedNodesSet { | ||
| nodes: nodes.into_iter().collect::<Vec<_>>(), | ||
| }); | ||
| } |
There was a problem hiding this comment.
It is probably easiest to just always send this message (rather than allocating the previous_selection HashMap each frame).
There was a problem hiding this comment.
I can't intuit which is better, but I'll take your word for it. When I or whoever makes the change, I assume they should also make the identical analogous change to the box selection code?
There was a problem hiding this comment.
I guess it doesn't matter very much either way.
There was a problem hiding this comment.
Leaving it for now, then.
| fn points_to_polygon(points: &[DVec2]) -> Vec<PathSeg> { | ||
| points | ||
| .windows(2) | ||
| .map(|w| PathSeg::Line(Line::new(dvec2_to_point(w[0]), dvec2_to_point(w[1])))) | ||
| .chain(std::iter::once(PathSeg::Line(Line::new( | ||
| dvec2_to_point(*points.last().unwrap()), | ||
| dvec2_to_point(*points.first().unwrap()), | ||
| )))) | ||
| .collect() | ||
| } | ||
| points_to_polygon(lasso_selection_curr) |
There was a problem hiding this comment.
Rather than allocating, consider a simplye point in polygon algorithm https://wrfranklin.org/Research/Short_Notes/pnpoly.html.
There was a problem hiding this comment.
Hmm, I feel the disappeal of needing to allocate, but I'm not sure how point-in-polygon helps. I stole click_targets.node_click_target.intersect_path from... uh, probably the box selection code, and I didn't look further because I knew it worked. I'd need to think about it lots and dig deeper into the code, but first impression: aren't nodes not points? We rather need nodes (rounded rectangles) in polygon?
That is, without some digging, I currently don't know how to get the bounding boxes of all the nodes.
There was a problem hiding this comment.
I guess it wouldn't matter too much.
editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs
Show resolved
Hide resolved
7e4eb0f to
03aa7f9
Compare
|
Made some initial tweaks, discussion above. Feel free to mark whatever resolved if you agree with changes. I suppose the last holdup is the "point in polygon" note that I'd be stuck on. |
|
Oh, hm. Looks like the hints only show esc/rmb to cancel, but not the extend/subtract hints that show up when using the artboard drag select tool. As you are indeed able to extend/subtract, should I add them through a commit here or leave it for a later mini PR? Searched |
0aa3860 to
0a50a77
Compare
|
Yes, feel free to include them in the PR here. |
0a50a77 to
9427062
Compare
|
Included 👍 |
|
!build |
|
|
On Mac, there's a discrepancy between the canvas which uses Ctrl and the node graph which uses Cmd (Accel). You should probably make both use both Ctrl and Accel. Since we'd like the node graph and the canvas to work with both Cmd and Ctrl on Mac, and Ctrl on Windows/Linux. |
124235a to
a42cad8
Compare
|
Could you please resolve the merge conflicts and address my previous comment? Thanks! |
|
Schoolwork has ramped up again, but I'll be taking a look at this within these next seven days. Big project due this weekend. Appreciate the nudge 👍 |
|
Sounds good 😸 Please just mark this as "ready for review" and reply with a comment once that's done. I'm marking it as a draft for now so I can keep it out of my active review queue. |
Closes #2532.