 Howdy guys, IndiePixel here. And what I wanted to do in this video is run through some tips and tricks when working with HDA. So we're going to start out super basic, and we're just going to learn how to create an HDA. Then I want to go and talk about SOP level HDAs versus object level HDAs. Then we're going to go and talk about embedding assets into our HDAs, and how to add a little bit of Python to our HDAs. So in this case, when I hit this button, it prints out, hi, IndiePixel, all right. And then we're going to talk about dynamic UI, so how we can switch our UIs right here. Pretty cool stuff. And then finally, we're going to talk about adding handles. So when I hit Enter on this keyboard, I can move this box around. Cool, so these are all some really good fundamental stuff if you are just getting started with Houdini digital assets, or learning Houdini in general. All right, so let's move on to the tips. All right, so let's start at the very, very beginning. So what is an HDA? Well, an HDA stands for Houdini digital asset, and these HDAs allow us to basically contain our functions or our graphs. All right, so we can reuse them over and over again. So starting at the beginning here, how do we create an HDA? So what I just did there is I went and hit Tab on the keyboard over here in the network view, and I typed in geometry. All right, and this is basically a geometry container. And this geometry container can have anything inside of it, like a box or a sphere or some complicated network that generates bridges or roads, stuff like that. All right, so turn that into, well, let's actually keep the box there. So I'm gonna grab it from my history down here. To actually turn this into a digital asset, let's go and right click on it. So I'm gonna say create digital asset, and this brings up this create new digital asset from Node. Now, it's always a good idea to give this some sort of name. So I'm gonna give it something like IP my box, like so. And we're going to then capitalize it. Now you don't necessarily have to do this. I just usually do it. And then now you have an option here. You can either save it to your documents folder. All right, so that way whenever you launch Houdini, your HDAs will be available to you. Or you can also go and save it into a project. So currently I have a Houdini project that I created. And inside of that I created an HDA folder. So I'm gonna double click that and then just save my HDA into that folder. All right, so I'm gonna hit accept and then accept again. And you'll get this little pop-up here when you're using the geo node to create a digital asset. So all we need to do is to say destroy all spare parameters because we don't have any spare parameters currently. And then what we do is we come into the type properties window here and we can go and modify the parameters or the UI for our HDA. So it's up here in the parameters view. So we can come over here and just hide all that because we don't need to see this stuff. So I'm gonna select invisible, hit apply and accept. And there we go. We now have a bare bones Houdini digital asset like that. That's ready for custom UI. All right, so that's how we create digital assets. Let's move on to the next tip on how to work with HDAs. Okay, so for the next tip, I wanted to really cover a concept that I find that is very confusing for people who are new to Houdini and working with Houdini digital assets making their own tools here inside of Houdini. And that's the concept of a SOP level HDA versus an object level HDA. So what we've just created in the first tip was an object level HDA because we're creating it at this OBJ level. All right, so if I were to actually go and hit tab currently, you'll notice that there's a digital assets option available right here. And our IP MyBox HDA is available there. All right, if I were to actually dive inside of my HDA, you'll notice that that tab menu is not available for us. And that's because we're now in a SOP level area, okay? And so that's what I really wanted to get across is we have an object level HDA and to create a SOP level HDA, we'd come inside of our geometry node and create a subnet. All right, so let's get a subnet work node, okay? And what we can do with this, we'll call this, I don't know, MySphere, okay? And inside of that subnetwork, we'll create a sphere. There we go, so now we have a sphere. Let's turn it actually over to a polygon, there we go. And now what we can do is we can go and turn this guy on and we can just go and save this as a digital asset. All right, so we'll call this IP MySphere. Alrighty, let's go and capitalize these guys like so. And again, I'm gonna save it into my project HDA folder and hit accept and accept. And when I do that, you'll notice that we actually didn't get the option to destroy spare parameters because these subnetworks basically are just containers for other nodes, there's nothing on it. But we can go and add our own UI to this stuff using this type properties window. So with that, we now have a SOP level HDA and if I were to hit tab now, remember I'm in inside of my box HDA currently, we now have a digital assets option here in our tab menu and we can create more MySpheres. So use these SOP level HDAs to create functions that live within inside of object level HDAs. Okay, so that's that concept that I really wanted to get across. Let's move on to the next tip. So let's talk about another feature about HDAs that's really useful that I find that people who are new to creating digital assets don't really know about. Now, if we go up to the side effects documentation here, you'll see this particular section here that is called referring to embedded asset files using OpDev, it's in the Houdini 17.5 digital assets. Now what this does is it allows us to embed files inside of our HDA. All right, so let's walk through this process. So I'm gonna double click my HDA that we have here and I need some geometry here that I can then import or embed into this particular asset. So let's go and get the pig head because it's fun and very Houdini. All right, so I'm then going to drop down a Rop Geometry output node. I'm gonna wire these two together because I'm gonna export this pig head out to just a file that exists on my hard drive. All right, so let's go select the Rop Geometry node and we're gonna come up here and we are going to export it to the geo folder in my Houdini project. So I'm just gonna call this the test pig head and we're gonna save it out as a BGO file. All right, cool. So now with that all set up, I'm just gonna hit save to disk and now that particular geometry is stored on my hard drive and I can verify that by dropping down a file node, hitting the display flag there and then just selecting the geometry. So if I go to my project folder, the geo folder and select that new file there and we can get rid of this stuff and we are good to go. So now we have our loaded geometry. Now the problem with this is it's pointing to an absolute path here on my hard drive. All right, so if I middle mouse click this guy I can see the full path for that particular file. Now if I pass this particular HDA off to another coworker or a friend or something like that, I'm just sharing my HDAs, they're not gonna have that path. So how do we get this geometry to go with the HDA? Basically that is why we are going to be using the embedded asset files using OpDev. So we need to use this OpDev operation right here. So let's talk about how to use that. I'm gonna get rid of this. Well actually let's keep the file node here because we're gonna use this. So let's go back up to our HDA. I'm gonna right click on it and say type properties here and what we are interested in doing is going to the extra files tab over here. This is where we can go and embed assets. So this is the first step to embedding an asset into your HDA. So go to the extra files tab and for the file name, I'm gonna go and select my testpighead.bgo file. And with that all set up, I'm gonna hit add file and now it is actually inside of my HDA. Now this will increase the size of your HDA but at least the geometry is there. All right, so I'm gonna hit apply and accept and then I'm gonna double click on my HDA to dive inside and let's come over here and get rid of this particular path. So now we're not loading any geometry up. So the way this works, we're gonna type opdef for operator definition. We're gonna do a colon and then dot dot question mark and the name of that file. So it was test underscore pighead.bgo and look at that. We're now loading up the geometry that is embedded inside of our HDA. So far to pass this off to anybody, the geometry would go with it. Very cool stuff. All right, so let's move on to the next tip. Another really useful aspect to creating HDAs and honestly to make them really more advanced and more dynamic is to add Python to them. So how do we go about adding Python to our HDAs? Well, there's one way where you could go and add a Python node. All right, so if we just type out Python you can add a Python node in there and write all your code in here as well. That's really more for geometry processing and quite a lot of other things as well but what if I wanna have a button up here on my HDAs user interface up here that triggers some sort of action inside of my network. All right, so let's go and take a look at this. I'm gonna open that type properties window there and what we wanna do is we want to go over to the scripts tab now. And inside of the script tabs we wanna add a new Python module. So to do that we're gonna come down to this event handler dropdown and select the Python module. All right, so what this does is it sets up a Python module that's inside of this particular HDA. And what we can do is we can write some Python. All right, so let's just write a really basic function in here. So I'm gonna say def say something for the function name and then we're just gonna have this currently print out something like, I don't know, high indie pixel. Yay, all right, it's our hello world Python function. All right, so now we've got that in place I need some way to trigger this so we can actually see the results of our function up here. All right, so to do that we're gonna come back to the parameters tab and I'm gonna go and create a button. There we go. And I'm just gonna call this my button for now. There we go. So let's go and call this press me for the label. All right, so now I need this button. So if I hit apply now over here you'll see that we have a button up here and it's not doing anything currently. All right, so if I press this what I wanna do is I wanna have it print out that function or run that function that we just coded up over here. So to do that, we need to come down to the callback script. This is how we hook this button up to that function. And I wanna make sure that it's set to Python. And now the code that we need to write inside of here is who.pwd to access this current reference or this current instance of this particular operator or this HDA. We're gonna say HDA module. So we can access the Python module that we created over here. So we're accessing this thing now. And then the name of the function. So we say say something and then parentheses. And with that, we're all set and ready to go. So let's hit apply and accept and hit press me. And there we go, look at that. Cool, so that pops out open. Now, if you wanted to not use the console let's go and close this. You can always come down here and open up a new paint type and we are looking for the Python shell. So now if I press this, it goes to here instead of the console, pretty cool. All right, so let's move on to the next tip. When working with HDAs, especially in teams you wanna make your UIs up here really dynamic. That way, as parameters are changing the UI is changing to accommodate whatever geometry is being displayed. Now, there's quite a bit of things you can do with this parameters. And one of the things I wanna talk about is how do we make our UI a little bit more dynamic? All right, so let's go into our HDA here and I'm gonna set up a switch node here between our box and our sphere. All right, this just basically allows me to switch between whether or not I want the box or I want the sphere. All right, so let's go and promote this toggle here to our HDA. So I'm just gonna right click on the little breadcrumbs up here and open up the type properties for that HDA. And what I wanna do is just drag and drop that slider there into my HDA. And now that means that it's now available up here and is now overriding the switch node. Cool, so I actually wanna turn this to a toggle. All right, so let's go and change the type to a toggle. Now we'll just call this the switch for the internal name and switch for the label. All right, so let's hit apply and awesome. So now what I wanna do is I want to have this display the scale of the box when the switch is using the box geometry. So this particular slider right here. And then I wanted to have it to display the scale for the sphere when the sphere is selected. All right, and I want those two sliders to be independent. All right, so let's go and make two folders here. All right, we're gonna call this the box, parms or params, there we go. And I'll call this the sphere params like so, awesome. So hit apply and accept. And if I were to jump up and out to the OBJ level or object level, you can see now I have two tabs up here. All right, and they contain both. But basically what I wanna do is I wanna say, well, when we're on the box, I can only see the box parameters. And then when I'm on the sphere, I can only see the sphere parameters. All right, so how do we set something up like that? So let's pop open our type properties again and let's make a little more room here. And I'm going to expose the uniform scale for the box. And then I'm gonna expose the uniform scale for this sphere. There we go, very cool. And what I wanna do is I want to create some sort of relationship between these two tabs based on the value of this particular toggle right here. So what we can do is we can say and utilize the hide when a particular value, like the switch or this toggle right here is true or false. All right, so to do that we can say, well, I'm gonna hide, so we need the two curly brackets here. So I'm gonna hide this particular tab when switch, I'm gonna move the cursor there, is equal to zero. Okay, and let's copy this. And then I wanna hide the sphere when it is equal to one. And I think I actually got that mixed up there. I want this one to hide when we're zero and I want this guy to hide when we're one. There we go. So let's set apply and let's take a look at this now. So let's jump all the way up and out. Now you can see that I only have the sphere parameters available. And when I turn this off, I don't actually have the box parameters and that's because I put it in the wrong spot. My apologies, there we go. Cool, let's hit apply and accept and there we go. So now we have our box parameters. So now we're creating a dynamic UI. And you can get really advanced with all this stuff. So I highly recommend practicing that. So let's move on to the next tip. Okay, so for our final HDA tip, I wanna talk about handles. So you might have noticed if you've been using Houdini for any length of time that if we dropped on something like a poly extrude node over here for this particular box and we hit enter, we get these handles over here, all right? So we can pull on these handles right here and then we hit escape to get rid of it, right? Well, we can actually build our own handles for this. So in this case, what I wanna do is drop down a transform node and I want the ability to drive this transform. I wanna be able to mimic this operation. So when I select the transform here and I hit enter, I wanna be able to pull up a gizmo like this. So I can move the box around, all right? And so I'm gonna keep that there and keep the switch highlighted or have the display flag on for that, all right? And what we can do is we can set up our own custom handles to drive that. And so the first step in getting that to work is to put in a float vector three for this guy because we need the X, Y and Z. And we'll call this the box pause and box pause for this, all right? I'm gonna apply and then accept and then I just need to go and open that type properties window again. And the reason is because that commits that new property to our HDA. So now we can actually access it inside of this handles tab. So let's go to the handles tab here and let's go and create a new transformer handle. This is basically the same type of transform handle you get when you highlight the transform node. And what we need to do is we need to come all the way down to the bottom here, okay? And we need to go and assign values for the TX, the TY and the TZ, all right? So if we were to actually come over to this transform node here and just highlight over this guy, you can see that the parameters are TX, TY and TZ. All right, cool. So if we go to TX, we wanna assign the box pause. So we need to scroll all the way down to the bottom here. So we wanna get the box pause X for our TX. We want the box pause Y for the TY, all right? And then for TZ, we want the box pause Z. Simple as that. So now we've got our transformer handle hooked up to our box pause. So let's hit apply and accept. All we need to do now is pass, let's turn this guy off there. All we need to do now is pass this value. So let's copy the parameter. So this vector three right here, down to our transform. So let's just override the transform here with our box pause value. So now when I go and hit enter on the HDA, so I'm gonna select the HDA over here, then hit enter while in the scene view, I get my own custom handle, and I can now take this and move it around. And if I were to switch, you can see the handle stays there, but we now have the sphere. So I can switch back and we can move the box again. Pretty cool stuff. All right, so I'm gonna close that out there. I hope those tips helped you guys out with HDAs. Those are some of the things that I've always, you know, wanted to share with people when they first start learning HDAs because they're really powerful. All right, thanks so much. Really appreciate the support.