Once you get further into messing with all of the menus and scripts, you may find just working in the shelf tool editor to be a bit cumbersome, as well as in some cases, it can even end up corrupting your shelf tool and losing a few or all scripts. I've opted for setting up a personal package that allows me to organize and control all of the things. It also allows you to share your package with others for personal purposes, or even if you are working as a team.
Here are all the things I would suggest setting up:
My IDE of choice is VS Code. You know the drill here, pick the one you like the most, google things that don't line up!
Install the Pylance Exstention, and then open up your settings.json file and add this.
// paths depend on your Houdini installation
"python.analysis.extraPaths": [
"C:\\Program Files\\Side Effects Software\\Houdini 19.5.303\\houdini\\python3.9libs",
"C:\\Program Files\\Side Effects Software\\Houdini 19.5.303\\python39\\lib\\site-packages-forced"
]
Now you can edit python and have access to the hou autocompletes which is helpful.
So, when you get deeper and start creating HDAs and scripts, you will notice the default saving location is always relative to some default Houdini location. With the package we are creating, the goal is to have a mirrored skeleton directory of the native Houdini folder, where you can build (and break) things without affeting the default stuff. This also makes it very easy to share and keep track of the chaos you have made.
To start off, create a folder somewhere that suits you. Maybe it's on the work NAS, or on Dropbox. The key point here is that it is not in your Houdini folder. In my case, I will call it LVTools.
Then you can jump to your Houdini preferences folder and go into the packages folder and create a new .json file. For organization purposes, I would suggest naming it the same as your package folder. In my case, I now have LVTools.json. Inside it, its pretty basic for now:
{
"env": [
{
"LV": "Z:/Assets/LVTools"
}
],
"path": "$LV"
}
Now you have 2 things. Houdini will load this folder at startup, and you have a path link that you can access with $LV in any path field. When saving things, now its pretty easy to link the relative to this new variable.
If you're really committed, you would initialize a git repo here too and commit and push your changes.
Now that you have you package set up and your variable working, you can start saving things to this package.
When working with HDAs, I normally set the path to Hip directory, then to custom. Then it's fast to adjust to your vraible. This is the least amount of work required to get to your file saved in the right spot.
Pulling a Paul Esteves and calling this a hack. :P
Sadly certain files are not "package-able" and need to be edited in the Houdini prefs folder. One of those is jump.pref, which we can use in this instance to add our new package variable to this file.
$LV
That's literally it, now when you open up the file explorer in Houdini, you can see the unexpanded variable on the sidebar.
This is a good timesave if you are often jumping around saving stuff. Certain menus (like saving the shelves) will benefit from this.
Often you ay find youself building little shelf utility scripts. I have a messy shelf with all the ideas I have, and once they become useful enough, I port them over to a main utility file, in my case, scripts/python/LVUtils.py.
With this file, there is the benefit of being able to create a bunch of helper functions I may use in multiple places and keep everything nice and neat. For example, if you want to always have a clean console when things go wrong, you could create a function like:
def lv_error(f, message):
print("------------------------")
print(f"Error running: {f}")
print("Logging error")
print(message)
print("------------------------")
Here the function takes two arguments, the function name and the message. In each tool you could have a simple try... except statement and get a clean log for each of them.
def lv_error(f, message):
print("------------------------")
print(f"Error running: {f}")
print(message)
print("------------------------")
def print_selected_nodes():
try:
nodes = hou.selectedNodes()
print(nodes)
except Error as e:
lv_error("Print Selected Nodes", e)
Now if the function ever goes wrong, you get a clean log for the error.
When working with an External Code Editor, you will see I often use import hou to get autocomplete suggestions. The only issue is natively the hou module errors out as needing self as the first argument for each function. This is easy to get around, as we can install Houdini Types.
To install these, its useful to put them in a location you can link to and also that is somewhat "linked" to Houdini.
To install these, open the Houdini shell by going to Windows -> Shell, then copy and paste this line:
python -m pip install types-houdini --target %HOUDINI_USER_PREF_DIR%/python3.9libs
It's important to do this in the Houdini shell, otherwise it just gets dropped into a location called "%HOUDINI_USER_PREF_DIR%".
Once that's installed, open up VSCode and install Pylance if not already installed. Open your user settings JSON and find the "python.analysis.extraPaths" line, or create it if missing.
Then, add 2 paths here:
"C:\\Users\\YOUR_USERNAME\\Documents\\houdini19.5\\python3.9libs",
"C:\\Program Files\\Side Effects Software\\Houdini 19.5.493\\python39\\lib\\site-packages-forced",
These 2 lines are easily got using the Houdini shell by using echo %HOUDINI_USER_PREF_DIR%/python3.9libs and echo %HFS/python39/lib/site-packages-forced.