 Howdy guys, India Pixel here. And in this video, we are gonna go through the process of learning how to detect curvature and more specifically curvature along roads. So I wanna be able to find the outside and inside turns so I can place things specifically in this example. I'm placing the guard rails here on the outside of the turn and the signs on the inside of the turn. And this is really useful because now we have a full procedural system in terms of placing these things along the appropriate part of the road. So as the road changes and the curvature changes, you can see that the guard rails are updating and the sign placement is updating. And so really crucial procedural modeling tip to learn when you're making stuff for like Houdini engine and stuff like that. So with that, let's actually take a look at how you hook this up. All right, let's kick this off by dropping down a geometry node. And I'm gonna call this finding a curvature like so. I'm gonna hit enter to dive inside and then I'm gonna go and create a curve. This curve will give us basically the basis for which we want to find the curvature for. Something like when you're working on roads and stuff like that in Houdini. This is very, very handy. So just created a curve, turn on grid snapping and just a really rough curve just to test this out. And hit escape to get out of edit mode there. I'm gonna drop down a resample node and we are then going to resample this at a length of one. And I'm gonna set this to subdivision curves just to make it a little bit smoother. Some more road like, like so. And then I'm gonna go and add my curve directions to this. So if you haven't seen the other video about hooking up curve directions, I highly recommend you watch it because I'm just gonna use my preset for this. I really just wanna cover finding curvature in this particular video. All right, so I'm gonna select my preset. You can also pause the video and copy it from there. With that done, I'm gonna drop down a sweep node and we are gonna set this guy to the ribbon for the server shape. I'm gonna set the width to something like four and I'm gonna set my columns to one. Now you're gonna notice that the sweep node is gonna produce some really wonky geometry there. And that's because our curvatures aren't actually producing any proper directions. And that's because in the resample node, we need to go and turn on the tangent attribute and our curve view attribute. I'm gonna go and change the tangent attribute name to capital N. And what that does is it actually produces flow normals or normals that follow the direction of the curve. So currently it's really hard to see if you hit D on the keyboard. We can go into the guides here and increase our normal. You can see that we're getting these flow normals here. You can make it even easier to see if you drop down an ad node and we feed that guy in there like so. And we just say delete geometry but keep the points, turn on the blue display flag and now you can see the normals reach one of those points there. So it's pointing in the direction that the curve is flowing basically. So let's get rid of this ad node here and now we have some geometry to work with. This is great. So what I'm gonna do is just pump this guy over here and we'll just say something like out road. Cool. At this point, now all we wanna do is drop down a measure node and just take a look at the basics of producing curvature here. So I'm gonna put in the measure node there and we're gonna set this to element type of points. This is very important for this particular technique here to find the curvature. We're gonna then set the measure to curvature and I always use the Gaussian filter there. And so now to view the actual results here, I just enter with the measure node selected. And you can see that we're getting red for the outside and blue for the inside. So really, really cool way of quickly getting curvature, especially when you're working on things like roads. You'll notice that we're actually getting red though at the ends here. So we're gonna have to write a little bit of a Vexico to take care of that particular thing. So let's keep moving forward. Now that we got our curvature value, we can actually start to work with that value. So just so you know, the attribute is called curvature and you can see if you have the geometry spreadsheet open over here that it has put that attribute onto each one of those points. All right, so that's what we're viewing right here. So I'm gonna actually hit escape over here in the scene view to get out of the edit mode for the measure node there. And I wanna split this up now into two curves. I'm gonna use the add node for that. I'm gonna delete geometry, keep points, go to buy group and we'll say skip every end point. Now you can also get, you know, the horizontal curves if you will, if you do groups of end points. So in this case, I wanna put stuff on the outsides of the road here. And yeah, so I want these particular curves like so. So we can now go and visualize this ourselves. Drop down a wrangle node. I'm just gonna call this curvature colors like so. And we are gonna go and assign our own colors to these. So let's go and write a little bit of code here. So I'm gonna say at CD, which is just the attribute for color is equal to zero. So you can just set it to black by default. And then I'm gonna do if that curvature. So we say f at curvature, like so, if that curvature value is greater than zero, then I wanna set it to red. So I'm gonna say at CD is equal to 100 or red RGB. So there you go. So now you can start to see we're getting some colors now for the outside turns. Super cool. So I'm just gonna copy this little snippet of code here. And we're gonna paste this. I'm gonna say if you're less than zero, then we are going to be green like so. All right, so now we've got all of our curvature colors. Super cool. We also do need to take care of these little end pieces here. So let's do that up here. Here's a really slick way to do this. I'm gonna do, so basically my goal is to find these points first. Now there's something very unique about these particular points. Let me actually comment this out up here. There's something unique about these particular points is that they only have one neighbor, right? A neighbor being a neighboring point that they're connected to. If you look at every other single point here, it has two neighbors next to it. So we can actually look for that and that's what I'm gonna do here. So we're gonna just do int num nays. Now that's just a variable name I'm assigning it. You can call it whatever you want. We wanna use that neighbor count effects function there. We wanna get the information from the first input there or this guy right here. And we wanna do apt pt num for the point number. There you go. All right, so if our num nays is equal to one, all right, that means we only have one neighbor. I'm going to just put your curvature value to zero. There you go. So now it's just black. All right, beautiful. So with that done, now I wanna be able to determine like how much of the actual inside and outside curve I wanna keep. All right, so to do this, I need to convert this to line or use the convert line node. I don't need the rest length attribute. I tend to turn it off just so I don't have a lot of attributes in my geometry spreadsheet. You can leave it on if you want though. So I'm gonna do attribute promote now. So we are gonna then go from points to primitive. So I wanna take that curvature attribute from the point and put it onto the primitive. That way I can then feed that into a wrangle node and remove stuff based off some rules, right? So I'm gonna do attribute wrangle node and we are gonna then go and rename this to say remove prims like so. Cause that's exactly what I wanna do on this wrangle node and then I wanna go and find or I wanna create a new parameter here called minCurvature. So let's just create a new variable first and then do a channel float or float channel call this minCurvature as well just for the label. And I'm gonna hit this little button right here to actually expose it. And then we're gonna go over here. We're gonna say if the absolute value, let's put that inside the parentheses here. So again, if the absolute value of f at curvature is less than the minCurvature, then we wanna remove the primitive. So we're gonna say remove prim and zero for the first input at prim num for the prim number and one to remove all the associated points. So now nothing is gonna happen because we have our minCurvature set to zero here. So we just increase this slider right here and we can start to remove set. So you can see if we were to template our road piece here now we're getting just the portions where we wanna start placing assets. So if this were like a racetrack, you'd have like the bumpers on the inside and you'd have the guardrails or a fence or something like that on the outside. All right, cool. So remember currently these particular curves are still all separated out. So we need to fuse these guys back together. So let's do a fuse and polypath. It's a good technique right there to get your curves back into a single curve. So now when I turn on the display flag, you can see that we have single primitives here. Perfect. At this point, we pretty much have all the data that we need except for all of our directions. So we need to go and produce all of our normal directions. So we have the flow of the curve from the original curve that indicates the direction of the road and then also all the directions that face outwards from the road as well. So we can place stuff out there. All right, so let's take care of that. Let's do this here. And what we need to do actually to do this appropriately is we need to assign the original primitive number to this. So if we come all the way back up to the top here to our ad node and we turn on our print numbers you can see that we have the zero and one. Well, we need to actually record that or at least stash it somewhere. So I'm going to go and drop down a wrangle node and I'm going to call this set ID. And to do this, I'm just going to run over the primitives and say I at ID. So we're going to make a new integer attribute that'll live on the points itself. So you'll be able to see in the geometry spreadsheet. And I'm going to give it the prim num. And we're going to leave it on the primitives there. Cool. So with that done, and we actually need to spell this correctly. So prim num, there we go. Cool. So now that we've got that on the primitives we need to promote it down to the points because it'll get destroyed when it goes through this convert line node. And so we just do an attribute promote here and drop that down like so. And we'll say we want to go from primitives to point and we want to transfer that or promote that ID attribute. So we pump that through and go down to our last node here, the split node. You can see that this ID is now in the points that survived all this processing right here. Cool. So now we can split on that. So I can say if the ID here is equal to zero. So we're going to say at ID is equal to zero. And we need to set that to points. So there you go. So we've got one half on one side and the other half on the other side. So now we need to develop our normals, the ones that are facing away from each other. So I always call these the away facing normals. Like so. And I'm going to pump that guy into there. And this is actually relatively simple to do. We just need to get the position from the other side. Right. If I were to drop down a null node over here and take a look at the point numbers over here. So let's turn on our point numbers here really quick. So we have zero, one, two, three, four all the way up to 18 there. And we have the same ordering and the sorting over here on the same side. That is why this is going to basically work. Cause I can just grab the position from the other side. So I'm going to call this other pause. And this is going to be equal to point and one for the second incoming geometry there. I want to get the P attribute, the position attribute. And we want to do at PT num cause the point numbers match on both sides. All right. And we need to make sure that we spell correctly. There we go. And then finally we're going to say at n is equal to normalize. We're going to normalize the vector that is created by subtracting the current position of the point from the other position. So we say other pause. And there you go. So now we have normals that are facing outwards. And if we were just duplicate this by holding down alt and left clicking and dragging and then I'm going to hold down y on the keyboard to cut the wires. If we just swap the inputs here we now have the opposite effect. So we can just grab these two guys and then hold down alt left click and drag to create a merge node. You can see now we have the normals pointing outwards. Like so. This is really useful because then what we can do is we can use a peak node here, turn off the recompute point normals. And this allows us to then peek it outwards from the road. So we can place stuff out there. Very cool. All right. So with that we also need to produce the flow normal. And that's relatively simple as well because we actually get that value up here. So this is coming in from there. So if I turn on my normals you can see that we actually have the flow normal up here. And so really in this curve there's, let's actually put in a new vector attribute called forward. So V at FWD for forward. And that's equal to at N for now. So I'm just stashing it on the point there. And basically the reason why I did that is because now they actually survive all the way through the graph. So I have this forward vector here. And we can actually visualize that. So if I were to drop down visualize node by hitting X on the keyboard, we can go and visualize this guy. So we can go and set the class to point. And we're gonna look at the forward attribute. It needs to be type of marker and a vector for the style. You can see that we now have our flow normal. So we know that both sides are flowing in the same direction. It's just that this is the outside turn and that's the inside turn. Cool. So now we've got all that information all set. Let's just split it out into outside and inside curves there. And to do that, I'm gonna do at CD.R is greater than zero and set this to points. And that leaves me with just the outside turn. So you can drop down a null node here and we'll say outside curves and inside curves. And there you go. And let's just merge these guys together. There we go. And let's put down the color for this. So it's more like road like here. And we'll just do something like a dark color here and just template that by holding down control and hitting the template flag. And then just hitting the display flag. And now you can see if I turn off all my components here. We have the inside and outside curves. So that's how you find curvature. Really useful technique for procedure modeling. I use it quite often. So I hope you guys really enjoyed that. Thanks so much.