 Howdy guys. All right. So in this video, what we're going to do is learn a little bit about how to use the glob module And this is really useful so we can actually just look into a certain directory of files and basically read all the contents of the files in that directory So if you have you know a hundred let's say height maps or text files or JSON files in a single directory Like I do here So here I have a bunch of height maps at least four just for this simple test And what I want to do is I want to read in all these height maps here and I want to basically reassemble the height field from these four tiled height maps and so what we're going to do is we're going to start off this video by First learning how to use the glob module so we can read in text from a all these text files and Perform let's actually take a look here at the example What we'll do is we'll basically just learn how to create this setup right here So each text file has a certain line in it and we're going to get all of our files we're going to read all the lines from all those files and then basically Create this set of texts and so once we learn how to do that We're then going to go and learn how to read in all those height maps And basically reassemble them into a height field Okay, so without further ado, let's get started All right, so let's create a geometry node here and I am going to call this my glob test glob test like so And we're going to dive inside. I'm going to make a sub network Because I want to make this a SOP level HDA and this is going to basically get files from Directory, I'm just going to say dirt there All right, and so I'm just going to right click on it and say create digital asset and let me put on my namespace and we will do our version number as well And I'll just get rid of these guys here for the actual label So let's do this There we go, and I'm actually going to save it into the directory My actual hip directory here, so I'm just going to make a new hd a folder And let's just save it right there hit accept What I want this to do I I basically want this to be a generic File reader so we can read in you know text files. We're going to read in png's Maybe even bgo's fbx files, right? And so we need a couple parameters in order to do that The first parameter is the directory in which we should actually look into and so I'm just going to call this file there and we'll call this file Directory like so there we go All that looks good. So this gives us the ability then to go and assign a particular Directory to look into so I have a couple set up here. So what I'm going to do is select this text files folder We're going to focus on these guys first And so if you middle mouse click on the label here, you could see it expand to the full path All right, so right now it's just using the dollar hip Because it the hip files right next to that particular folder All right, so next thing that we want to do is we want to Put in a string and this is going to be our Suffix or file type actually it's called file type It'll be better. So file type There we go and the type of files that I want to look for is txt so text files Cool. So with that information we have enough parameters now. We can go jump inside of our hda here And all I'm going to do is I'm just going to drop down a null node here So let's do a null node and then a python node All right, very cool So this is going to get all files and set adders Something like that And I'm just creating the null node just to make a little network out of it. It really is just this simple You don't necessarily need the null node there. Then I'm going to put output node there just to Signify that this is the actual output There we go. Cool. All right, so let's jump into our python node and get a couple things set up So make sure you also have the python shell open if you don't you can always hit one of the plus buttons on any of these Panes up here and you could actually bring up the python shell like so Cool. All right, so we need to import a couple modules first So we're going to import os and then we're going to import glob. That's going to be the focus of this video all right, so with that done We now need to get access to our Parameters on our hda. So there's file der and the file type All right, so let's do that first To do that we need to get access to the hda. So we're going to say hda is equal to node dot parent All right when They say node they mean this particular node. So this node that we're actually on So now we have the parent What I want to do is I want to say a file der. So that's our variable And we're going to say hda.parm and we want to get the file der And then we want to eval that as a string like so And then we want to get the file type So we know what files we're searching for So I'm going to say hda.parm and we're going to do a file type It's easy as that and we'll also eval that as a string There we go so let's uh Let's build a path here. So let's put in some comments here. So let's get harm data And then we're going to get or build path Because we need to build a path for this all to work for the glob to work And so our path is going to be equal to our file der like so plus Actually, let's just do that first and then print out that so we can see what we got. So let's say print path There you go. So we have a path to our text files folder So now if I were to add on let's say add on the file type here You can see now we have this TXT so we need to add a little bit of information For the glob to actually work and that extra information is a Astrict like that or what is referred to as a wild card and then a dot because we also we want to turn this into a file type look up All right. So now if we were to print that And we also need to make sure we add another Here Plus symbol there. So now you can see we have the wild card and we're going to be searching for all things that are text files within that directory All right. So now that we've got that all set up Um, we can easily now Get all the files. So let's say get all files like so And to do that, it's actually quite simple. We're just going to say a files is equal to a glob dot glob And provided the path to look at like so And to commit the code what i'm doing on the keyboard is i'm using control enter To commit the code rather than just clicking out of there. It's just a quicker way to do it so Now what we can do is if the glob module actually finds a bunch of files using this particular file type It'll fill this files variable which becomes an array automatically And then we can actually loop through it for each file. So i'm going to say for a file in files Let's just print the file. So we'll say print file and see what we get. So control enter Now look at that we get all of the let's actually Yeah, we're fine now. Let's do that one more time make a little bit of space here And I'll just hit space bar and then control enter. There we go So we're getting test zero zero one text test zero two text And test zero zero three text. So what I've done ahead, I've just gone ahead and Done this already so you can see we have our three files in here, right? And in each one of those text files, I have a single line of text Just for this example Once you get the hang of this you can do what you know, whatever you want with these particular files All right, and so What I want to do now now that we have access to the file All right, let's first check We're just going to check to make sure that it is in fact a file. So we're going to say is file We don't want to work on anything else. That is an empty file All right, so we just want to do a really simple check We're going to say if it is a file then we can actually do something with it All right, and so what I want to do at this point now is I want to get the The text from that text file And so all we need to do in this particular case is say f is equal to open And we're going to going to use path or actually file Excuse me, and we just want to read it. So I'm just going to use the mode r for that All right, and so for each one of those let's print f dot Read line like so Look at that. We have a little python This is how we use the glob module pretty cool. Hey All right, so now we're actually rolling through each file that we found and pulling out the data that we need Very cool. So let's actually store that and then a sign or actually add it to a detail attribute So what I'm going to do is I'm going to create a new variable called lines And this is going to be equal to an empty array and we're going to fill it All right, so to fill it we're going to say lines Is equal to I'm sorry lines dot append F dot read line like so All right, and so now if I were to Exit out of the loop over here and print Our lines array You can see now we have all those guys in an array. Which is perfect because we can add an array now to Our geometry as a detail attribute. All right, so let's do that Let's make a little bit of a comment for us. So we're going to say create um detail adders like so And what I want to do is I want to say geo. All right, so that's coming from up here By default the python node comes with these two guys already filled out for you So we need to access the the geometry For this particular note and we want to then add an array Atrib like so And the first argument for this is the who dot atrib type and that's going to be a global for a detail attribute And then we want to call it lines And then we want to declare the type Of attributes so attribute data dot string There you go Cool So you notice once I hit control enter on the keyboard. I now get A new array attributes in the detail context here And so we need to set it. So now I'm going to say geo dot set global atrib value global atrib value And we want to first assign the name That's how we get the research for the actual attribute. Then we want to assign it the lines And there you go. So now I have my array assigned with those Text file values The other piece of information that we're going to need is the actual count Because we're going to loop through this and so I need to actually extract out the count. So to do that It's it's actually quite simple. We're just going to do a geo dot add atrib and I need to capitalize that so add atrib like so we'll say who dot atrib type uh Dot global because we want it to be a detail and we're going to call it count Well, let's actually make a little bit more detailed. So file count And we're going to do the length of Lines right here like so Now look at that. So now we have a new detail attribute And because it's an int you can assign it right away. I found that with arrays you need to first declare Or add the attribute array and then assign it All right, very cool. So now we've got our count and all of our text information Cool, so we can jump out of here. I'm just going to save this guy like so Uh, what we need to do now is loop through this. So I'm going to create a for each number loop here There we go And I'm just going to wire that guy in like so and I'm going to call this my loop data All right, and so at the for each end node here, I am going to Get our detail attribute. So I'm going to say detail and we're going to get that information from our get files hd a And the attribute I'm looking for is the file count And we just need zero because it's just a single value. So if I were to click on this now We get a value of three which matches our file count Very cool. So on every iteration, uh, I want to Create some text some geometry using a font node here And then what we're going to do is we're going to merge it together like so And then pass it into the final output here and hit shift s on the keyboard to get my wire designs changed All right, so how do we get the line? from um our array over here And so I'm actually going to create a wrangle node for this one attribute wrangle node And we're going to wire it in on this side over here. I'm going to call this curve file And we're going to create it as a detail attribute And all I need to do is also wire in the loop data here into that second input And we need to get the iteration. So I'm going to say int iter is equal to detail And we want the information from the second input. So we put one right there And I want the iteration value There we go And zero So that will get us the current iteration which we can then use to Get a particular index value from our array All right. And so to do that I am just going to do s at curve file Is equal to I should say curve text Like so it was equal to our detail And actually we already have we don't need to use a detail method here. We can just do s array at Lines like so And then pass in the iter value there So now our curve text is pretty cool. Hey And that's the last one in the list because We can come in here and actually do this here. So as I roll through it, you can see the text is changing Awesome. So let's go now and set up the font node so we can access that and so to access that Uh, we need the two backticks and we need the detail s And I'm going to get the information from our curve file node and we just want the uh Curr text I think is is that what I called it? Yeah curr text There you go So now if we take a look here Look at that pretty cool. Hey But you'll notice that when we combine them all together. They're all on the same line So all we really need to do and you could do this in many ways But we could also come in here into the font node and change the origin So we're going to say detail and we want to get it from our loop data node And we want to do iteration And there we go And then let's just negate that so it goes ascending there So there you go. It's got hello python. This is how we use the glob module pretty cool. Hey All right, so with that, let's move on to doing the height field or height map assembly All right, so let's do A little bit of height map assembly. So I'm going to call it that So I'm going to drop down new geo node call height map assembly And let's go and grab our hda So I'm just going to make sure I save the node and then I'm going to lock this particular instance of it Do a control c to copy it And then paste it in here because we're going to update the code to take into account The fact that we're working on height maps currently our code Assumes that you're going to be working with text files, right because we're doing this read line right here And when it comes to the height maps, we really just need the file, right? And so Let's update our code to handle that. So one thing I'm going to do is I'm going to go and add a new toggle up here So let's just drag and drop that in here and we'll say this is is height and I'll call it Is height question mark And we'll hit apply So if I toggle this Basically, we're going to switch the code and in this case now I want to look for a pngs All right, you could also do the if check based off of the the file type as well I'm just going to use this this toggle right here for right now All right, and so we need to go and get that particular value So we'll we'll say is height for the variable name And we'll say hd a dot palm and we'll look for Is height like so eval that as an int There we go cool All right, so I'm going to actually move this lines array down just below our glob method there All right, and I'm going to do an if check. So I'm going to say if Not is highly me actually put this here. There we go Not is height meaning it's false Then we're going to treat this as a text file and read the lines from it Else we are going to process it as though it were image files or height maps in this case All right, and so I'm going to Store it into an array called height maps Like so you more than welcome to change that around a little bit There's a bunch of ways you could do that. So you could say for a file in files like so Again, let's check to make sure that is an actual file. So os dot path dot is file We'll Pump in the file value there And then we want to basically just assign That to our array. So we'll say height match dot append file like so All right And we also need to treat our Array a little bit differently. So file count will work just fine And actually we could change this around the files like so there we go And So that works just fine, but this one Actually should go in here Like so because it's dealing with the the text. All right, so let's just uh Get this situated and make a little of space for All right, so Now we've got that all cleared up that should work. We just need to come up to our hda and change our Folder to height maps here and there we go. We got a file count of four, which is perfect because I have four height maps in there and I need to Make sure now I create The height map array attributes And we'll do that again Outside of that for loop there. There we go And this should be spelled appropriately Not that it's super important All right, we'll call this height maps And we want to pump in Height maps that array and assign it to the height maps array. That is the detail attributes There we go. So now we have all of our Not really really long here Let's actually print this guy out over here. Let's just uh Do a print right after this guy. So we'll do a print height maps There we go. Cool. You'll notice though that we're getting this backslash right here for the the height Map itself and that's actually not going to work for Our particular height map file node. It'll actually throw an error and so For each one of those files. Uh, what we need to do is actually do a file is equal to file Dot replace and we need to do an ossep. So ossep And replace it with a forward slash like so So now let's actually make a little space for ourselves And I'll just hit space bar control enter. You can see that now we've replaced those two back slashes with the forward slash there perfect All right, so now we have all the information that we want We have our file count and our height maps and so uh this point. Let's save our hda And um, just get our height maps assembled. So I'm going to drop down a for each number And this will loop through each one of those height maps and basically creates a High field for it. So let's do a loop data for the name. That's what I usually like to call it And then we're going to need a height field and in this case You probably want to you know wrap this up into an even bigger hda But in my case, I know that the the file size for each tile is 506 All right, so that gives me a Tile right there and then what we need to do is um get the height field file node like so All right, and we want to assign this to the height All right, and the file Is the one of the files or the current file in the loop here If I go to here, it's one of these files. So we need to get that curve file So let's do an attribute wringle and we'll say curve file like so And we'll pump our loop data into that first or second input there And let's just do a detail So let's get our iter again. So iter is equal to detail from the second input And we want to get our iteration like so and zero No, so that's the current iteration and that needs to be an int. There we go And then we want to get that curve file. So s at curve file just like we did before Is equal to a detail And we can actually just access the array again. There you go s at height maps and then the iter there you go and It's not being populated there. Let's see if We have oh, yeah, there we go. So curve file And I do want to actually merge each iteration But I think I need to change so we have fits and put so yeah, that's good right there Um, let's just make sure that on each pass we just get rid of the curve file So let's do an attribute delete at the very end here Once we've done that and we will delete curve file So each time basically we run through this We should get The curve file. So let me actually select this guy right up here Yeah, so curve file And let's actually pin that So then I can see And it's actually kind of see because it's it's hard to see because it's so long Yeah, so there we go. It's working though All right, so let's uh unpin that and Let's now assign that curve file. So we just need to do The two back ticks and we're going to do detail s And we're going to get the information from the curve file node We'll say curve file And we don't need to assign anything there And then let's actually merge This one together down here Hey, it looks like this guy's having a bit of a time here Oh, it's because the curve file is empty on that pass there So let's go and check our Yeah, so we have our height maps right here It's called height maps and we're getting So as that height maps Let me misspell it Let's actually see here. Hold on a second Let's do um Another array we'll call this maps is equal to s array height maps What does that give us there? Yeah, so I give this the same deal So let's just see if I can access that now. So we'll just say um At maps itter Let's actually click on this guy down here And then click on this guy It was pretty odd But this isn't working for me Let's try this Sorry about that. Let's see a string and we'll just make a local variable And that is equal to that guy And then we'll just say maps is equal to curve file And that is still ending up empty as well So i'm thinking that it just doesn't like to access the array that way. Let's let's try detail function. We'll say zero We'll say a height maps and zero See if that works and then click on this guy Let's do a single pass here. See that works So that populates the curve file Interesting. So that's populating it perfectly But then when we go and turn it off Oh I didn't set the count. I am so sorry about that guys. So let me actually put in the detail here And I want to get the account from our Get files from dur. So we need to do dot dot forward slash get files from dur And we want to get a count or file count There we go. And then we just need to put in There we go Let me turn this off now. All right. So now we're good. I'm really I really apologize I don't did not mean to waste your guys's time there But it happens with this stuff All right, so now that we've got that all sorted out. Um, what I need to do is um We can actually set the height here. So let me actually I also need to set the size. So let's set this to 505 And I'm doing that because When I exported it I added a one pixel padding to it Let's put the height scale to 100. So now we have all of our height tiles Right here all stacked on top of each other So we need to move them. Uh, basically by the iteration So I'm going to use a height field x form or transform Like so and for this first one, I'm going to take care of the x axis So we're going to translate it here. So to do that I'm going to say detail So detail and we want to get the information from our loop data like so and iteration And zero and then I want to do a mod two So that way we get this pattern of zero one zero one, right? And that that works for the number of tiles So basically I have four tiles. I cut that in half. And so that would be whatever Modular you use and I want to multiply that by a 505 All right, so let's take a look. So now we got these guys On the x axis, let's do the z axis now And let me actually just put down another one just to keep these guys separated here So let's actually copy this because it's basically the same. We just want to divide it rather than Do a modulus. So I just want to do a divide And I also need to floor it because we are getting some remainders from that There we go. Cool. Very nice All right. So now we've got all of our tiles. I'm all hooked back up Very cool Last thing really all you need to do is just drop down a height field splice So height field a splice And then I'll turn it back into a terrain for you From your height map. So let's say, you know, you're exporting out of like world machine or guy or something like that And all you have are, you know, the height maps It looks like I am getting a little bit of a pixel offset here Let's go back up here And Let's do 506 Should be 505 Let's actually do it grid spacing Two was the original grid spacing I used No, I didn't like that at all It's basically just scaling it And I think this needs to be 505 as well Well, we'll leave it there and that's basically gets us Our height map tiles are Basically got the main concept across. I just had to, you know, figure out the one pixel offset there at the ends Um, but yeah, there you go. So if you also wanted to recenter it, you can also drop down another height field transform Over here And you can do the centroid There we go. So we do centroid And zero dx Negate that And we'll do times zero point five I believe Nope, we just need the whole thing And we'll just copy that and Do dz There you go. So now you're all recentered up Cool All right, so that's what I wanted to show. That's how we go and use the glob method to go and find files. Thanks so much