Selecting Furthest End Points on a Prim

   917   15   3
User Avatar
Member
7 posts
Joined: May 2019
Offline
Hello! I've been working on a project where I'd like to fill in irregular 2d shapes with splines/curves connecting along the length of prims (or a specified direction/vector), but I'm not sure the best way to go about doing this. It'd be even better if I could average each prim to a curve, and then use that as a direction to guide the paths that will fill the prim. I've gotten kind of close using a few different techniques. I've tried sorting based on an assigned attrib (and then a vector) and adding based on the grouped pairs, but my setup is crude/inefficient. I've also tried creating a 2d volume and filling it with trails based on the tangentu attribs of the prims, but that has more more swirling and irregularity than what I'm aiming for.

My next thought is that the best path would be to create a vector along the 2d plane from each point on the prim for a blended or averaged direction (maybe by specifying a lookat axis/vector?), and then using that to drive the sort and add, but I fear my vex knowledge isn't quite as advanced yet.

Any advice would be greatly appreciated!

Attachments:
image_001.png (214.5 KB)
image_002.png (220.7 KB)
image_003.png (884.6 KB)
image_004.png (1.2 MB)

User Avatar
Member
435 posts
Joined: Aug. 2018
Offline
Maybe this thread might offer you some ideas:
https://www.sidefx.com/forum/topic/87448/ [www.sidefx.com]

and related to that:
https://www.sidefx.com/docs/houdini/nodes/sop/pca.html [www.sidefx.com]
Edited by Mike_A - Oct. 19, 2026 10:41:50
User Avatar
Member
315 posts
Joined: July 2013
Offline
Check the skeleton2d node, it sort of does what you draw in the screenshot.

There is also a 3D version.
More code, less clicks.
User Avatar
Member
752 posts
Joined: Sept. 2013
Offline
Hi alec-enrqz,

I think you might be looking for the longest shortest path on each island, weighted towards the middle.

Edited by Konstantin Magnus - Oct. 19, 2026 17:16:37

Attachments:
Longest_Shortest_Paths.png (47.0 KB)
longest_shortest_paths.hiplc (240.2 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
7 posts
Joined: May 2019
Offline
Jonathan de Blok
Check the skeleton2d node, it sort of does what you draw in the screenshot.

There is also a 3D version.

Using the labs straight skeleton 2d works pretty well for creating a sort of fitted average of the groups! There's definitely some clean up to do, but that's part of the way there. Would I be able to use that curve to drive a direction for sorting the points, so I could connect them across each other from there?
User Avatar
Member
7 posts
Joined: May 2019
Offline
Konstantin Magnus
Hi alec-enrqz,

I think you might be looking for the longest shortest path on each island, weighted towards the middle.

Image Not Found

Interesting! This is created using existing points/edges on the prim though, correct? The edge transport is creating a weight attribute, and then you're find shortest path to group points not part of the path to blast?
User Avatar
Member
752 posts
Joined: Sept. 2013
Offline
alec-enrqz
Interesting! This is created using existing points/edges on the prim though, correct? The edge transport is creating a weight attribute, and then you're find shortest path to group points not part of the path to blast?

Yes, this needs primitives and yes it's only keeping the longest of all shortest paths.
Btw. you can fill 2D curves with a mesh using the planar patch from curve-node.
Edited by Konstantin Magnus - Oct. 19, 2026 18:53:35
https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
752 posts
Joined: Sept. 2013
Offline
Alternatively, you could use fiedler vectors to draw curves through islands.

Edited by Konstantin Magnus - Oct. 19, 2026 19:06:17

Attachments:
fiedler_trails.hiplc (243.2 KB)
fiedler_trails.jpg (49.5 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
7 posts
Joined: May 2019
Offline
Konstantin Magnus
Alternatively, you could use fiedler vectors to draw curves through islands.

Image Not Found

This is fantastic, thank you! This is a lot closer to what I'm trying to do, though I'm not certain I understand the math behind it. The fiedler value is a float value defining connectivity across the polygon shape? Then you're using the measure to create a gradient and the tangent field to drive the direction of the trails created by the walkonsurface node? Do you need the gradient and tangents after you have the fiedler value?

What are the values coming out of the laplacian node that are being fed into the linear solver? After you've sorted the points by their eigenvalue, the point wrangle is creating pairs of points between the unsorted and sort prims based on the eigenvector, then reading the eigenvector value at the point on the sorted polygons to get the fiedler value?
User Avatar
Member
752 posts
Joined: Sept. 2013
Offline
Glad you like it. I think you can omit the tangent field and just use the gradient vector of the fiedler scalar field to drive point tracing. The linear solver outputs points for each eigenpair for the point wrangle to extract the second one of them and assigning each fiedler value to its corresponding mesh point. The Laplacian node outputs sparse matrices with coefficients, neighbour point indices and weights for the Linear solver. You can inspect the eigenvector values and the matrix data closer by right-clicking on them in the geometry spreadsheet.



Feel free to upload another sketch so we get a better idea of the kind of result you want.

Attachments:
inspect.png (72.3 KB)
fiedler_trails.hiplc (285.0 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
7 posts
Joined: May 2019
Offline
I think the fiedler trails gives me what I'm looking for! Is there a way to bias the trails in a particular direction, like if I want to have them more facing along the X axis or something? The result I was able to get works really nicely, so now I can get into the minutiae of dialing everything in

Attachments:
image_007.png (887.7 KB)

User Avatar
Member
7 posts
Joined: May 2019
Offline
Once I have the curves generated from the walkonsurface, is there a way to reduce the amount of curves output? Like can I create an average of curves, or delete/merge ones that are too close to a neighbor?
User Avatar
Staff
138 posts
Joined: June 2024
Offline
So I had a look at this in my personal time out of curiosity (don't want to set an expectation here for the type of answer SideFX employees generally will give). I think I have a solution that matches your second drawing, assuming that's what you ultimately want. I have a switch that either lets you keep the lines parallel and lose a bit of the original shape, or keep the shape and have the lines be less parallel, depending on your needs.

I used a node from our muscle workflow called Fiber Groom, which calculates a direction vector, `materialW`, that corresponds to the longest axis of each piece.

I then used a Match Axis SOP to rotate each piece so that the longest axis aligned with the z-axis, and that allowed me to set up a bunch of grids in the x-axis perpendicular to the surface which I did a Boolean Shatter with to create the lines.

You can then either fuse the original points to the new points, to keep the lines parallel, or fuse the new points to the original points, to preserve the shape.

Finally I used an extract transform and copy to points to rotate the piece back into its original shape.

Kudos to Konstantin Magnus for the idea for the quick setup of the shapes.

Attachments:
parallel_lines.png (105.8 KB)
preserve_silhouette.png (109.2 KB)
polysplitalonglongestaxis.hip (288.0 KB)

Liesbeth Levick
Technical Director: CFX
SideFX
User Avatar
Member
7 posts
Joined: May 2019
Offline
So I had a look at this in my personal time out of curiosity (don't want to set an expectation here for the type of answer SideFX employees generally will give). I think I have a solution that matches your second drawing, assuming that's what you ultimately want. I have a switch that either lets you keep the lines parallel and lose a bit of the original shape, or keep the shape and have the lines be less parallel, depending on your needs.

Whoa, this is incredible, thank you! I've never used any of the nodes from the muscle workflow, so this is really cool to see. The issue I'm currently having with the fiedler values is the enormous amount of curves being output, which I'm struggling to figure out how to merge or average so I can get a more usable amount of curves across the polygon islands. It seems like this has a more controllable output for the boolean shatter, by adjusting the length of segments within the foreach resample. If I have a significant number of islands, rather than matching transforms for every island, would it be simpler to match the bound of the shape along materialW, and then rotate the grid(s) to match that?
User Avatar
Member
752 posts
Joined: Sept. 2013
Offline
alec-enrqz
would it be simpler to match the bound of the shape along materialW, and then rotate the grid(s) to match that?

You could try the divide node's bricker after rotating the pieces.

Attachments:
island_stripes.hiplc (215.5 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
752 posts
Joined: Sept. 2013
Offline
alec-enrqz
is there a way to reduce the amount of curves output?

It might be easier to reduce the number of trail points right from the beginning.

Unless you want to dive into "evenly-spaced streamlines" (back online soon):
https://forums.odforce.net/topic/50074-evenly-spaced-streamlines/ [forums.odforce.net]
Edited by Konstantin Magnus - today 08:28:57

Attachments:
fiedler_trails.hiplc (248.9 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
  • Quick Links