Take and takes: part 2 — Where and about.

end thoughts …
All appears to work reasonably well in h11.1.xxx –Although, I have yet to test it in any  harsh or production environment. So, anyone who does, feel free to email me some feedback, it’d be appreciated.

There’s some conveniences I ran across in hscript docs that I might like in python. As mentioned in part 1, I wanted to keep the module clean, but I may implement a companion module, if I find myself really wanting it. I also made a fair attempt to add docstrings tha’tll show up in the help popups in Houdini and to keep it generally looking the same as the rest, but some finer ui things like dragging a take into the py shell and expecting the object aren’t working

There are some methods of Take object in particular that are best guess where assumptions had to be made as they were necessary features but have some error potential going forward. There are some places where there was no sense in implementing a feature and still others that are necessary ‘hacks’. This is all noted below.

what is available for download
This scripts are available in takes.py in the script downloads section as well as incorporated into eyevexTools py modules also available for download

basic use
import eyevexTools.takes

# use for creating a new take….
mytake = eyevexTools.takes.Take(‘mytake’)

# it is recommended to use find or a listing function instead of the wrapper directly
mytake = eyevexTools.takes.findTake(‘mytake’)
curenttake = eyevexTools.takes.curTake()
roottake = eyevexTools.takes.rootTake()
alltakes = eyevexTools.takes.allTakes()

caveats

  • unable to implent the XML export as the format can be arbitrary
  • although it is impossible to know is the path would be returned in the presented format, It was needed for this implementation but may not be compatable
  • It is not clear if insertTakeAbove and moveUnderTake will be returning parent or child. I assume it to be child.
  • EYEVEX_TAKE_PREFIX is a hscript env used to store the take prefix (when not default), as hscript provided no facility to retrieve it after being set
  • allAllParmsOfNode method in the docs is assumed a typo/error and that it is method addAllParmsOfNode -which is how it appears in this implementation, but can be a risky assumption.
  • asCode method doesn’t include the code for wrapping the take

(|;-D>

Take and takes: part 1 — What and Why.

Takes in Houdini are an extremely powerful and flexible way to nondestructively try different parameter values in the same session, create render passes for lighting, and create and compare variations. In the series of posts on FauxLiner, we looked at reasons and ways to combine and wrap hscript with hython.  The takes libraries is more elaborate but is done in a similar fashion and for similar reasons.

The takes system is currently accessible from hscript but not hython.  As takes is so powerful and versatile, it is often needed from python, particularly as larger pipeline and tool scripts move to hython. This often results in wrapping hscript take commands in similar looking python code. For example,we can  look at a simple take related command, takename  This can easily be wrapped in pyton, making an equivalent accessible in HOM for take renaming.

Docs Usage example shows:
takename take new_name

# this can easily be python wrapped as
def takename(take, new_name):

hscript_cmd = ‘takename ‘ + take + ‘ ‘ + new_name
hou.hscript(hscript_cmd)

return None

And this is done and done often. It is very common to redevelope or rebuild similar scripts and tool utilities again and again at different jobs or in different projects. Wouldn’t it be easier to have all these common wrapped Houdini take related commands available in a python library while awaiting the official hython takes release ? — the presented python modules attempt to do just that.

This is a ‘stop-gap solution’. Lets briefly go over what is typically meant by this. In short, there is a time lag or a ‘gap’ between what is needed (in this case python access to Takes) and what is available (the official hython release by sidefx is not in current builds). We need to ‘stop’ the gap with an implementation or ‘solution’. Stop-gap solutions aren’t usually elegant and often rely on brute force (we could have this library pull from the HDK C++ libraries which would be more efficient and flexible, but sidefx should eventually be distributing this, so we avoid al ot of extra work by taking a efficiency hit by wrapping hscript). Stop-gaps are intended to be temporary measures and come in two basic varieties: The first is a branch of a tool, project or pipeline that “does the job” and when the gap is passed will be completely discarded as the proper released solution moves into the main fork. The second type moves inline with the tool, pipe, or project and is intended “to transition” to the final solution, which then in itself will be transitioned to from the stop-gap solution. The second variety tends to get employed when the time frame for the final solution is long, unknown, or of unknown stability/compatibility. The Takes solution presented in these posts is of the latter variety.

The first decision that was needed is whether or not to present the wrapped hscript takes commands in a similar 1:1 fashion as shown with takename above. For those who already know hscript, it would be very easy to guess the py equivalent. But wait… When looking in the Houdini docs it would appear there are already some indications on how this may be implemented, if we look at hou.takes and hou.Take. These two docs have what appear a fairly complete list of functions to deal with takes, what methods the Take object will eventually employ, and what kind of values we can expect to be returned by the functions and class methods. Although the docs lack any real description of use, some assumptions can be made by drawing parallels with what is already known about the hscript implementation. The function naming is also descriptive and provide insights. i.e. It can be assumed that…

hou.Take.addParm(self, node)

…will eventually add a parameter to the take that this instance of hou.Take represents. Because we have access to the mentioned information on the possible eventual sidefx implentation, this library models itself after it, and NOT a 1:1 hscript wrapper. This provides additional advantages…

  • forward compatibility (easy upgrade path): by keeping the function names and return values in sync with what we expect the official hython release to be we ease upgrading. Ideally it would be as simple as finding all “eyevex.takes.Take” and replacing them with “hou.Take”, but in reality its not likely going to be THAT easy.  We can avoid introducing additional problems by resisting the temptation to ‘improve’ on the functions and args presented in the docs with changes, and keeping such enhancements in a separate module which can continue to be used, even after the official release.
  • full advantage of pythons object oriented features: when the rest to tools using the library are taking advantage of hython OOP features it could be awkward to deal with the separate procedural style of straight python wrapped hscript
  • reduced breaking changes if the ‘gap’ lasts longer than anticipated: since it is unknown when the official implementation will arrive, there remains the possibility this could fall into long term or indefinite use. Especially considering the library will be distributed, by keeping the function names and return as close as possible with the docs, all the function bodies in between can change. The initial inefficiencies in a quick stop-gap solution that are acceptable may become cumbersome in long term use. This allows the function bodies to be rewritten for greater efficiency or even pull form HDK level (if for some reason this became worth while) without having to alter any code utilizing the modules.

Continue to the next section for download information, as well as potential differences between the presented modules and what will eventually ship in the hou module with Houdini.

FauxLiner: part 4 — Now What.

end thoughts …
In these posts we looked at how to make a tool to help transition new artists to Houdini and allowed a different accessible way to select nodes at different levels. We talked about various hiccups that one might run into when developing such a tool including mixing languages, issues with documentations and reversing in script what was previously done in the GUI.

There are some areas that could be far more compact but for the sake of instruction readability is favored over compactness. A python floating tab could have been used as well, but keeping it in hscript allowed us an easy way to devise the script in steps and allow the title to display cleanly in the floater.  The technique of returning a python ref to a preexisting FauxLiner helped keeps the function simple in addition to making sense since having multiple floaters would not offer anything additional.

what is available for download
This script is available in floaters.py in the script downloads section as well as incorporated into eyevexTools py module also available for download.

In addition to FauxLiner, floaters.py in both cases also contains “Quick Bundler’ (floaters.quickBundler() ). This is a floating panel with a bundlelist pane paired with the FauxLiner.  This is made specifically with rapid bundle creation and editing in mind. I assign “add to selected bundle” in the hotkey editor to CTRL+” Then with the Quick Bundler open, you can rapid bundle by:

  • activate/create bundle on the left
  • select node from any/all levels via the FauxLiner on the right
  • just move pointer over left side and press your hotkey
  • repeat …

caveats

  • currently with the quick bundler, there cannot be any other floating bundle lists open. This is a known issue.
  • after opening either floater, you may go to list mode in the node graph for the next network you create. It seems to only do this once. Press ‘t’ over the node graph to toggle it off list mode

FauxLiner: part 3 — How.

So, now we have a good idea of what we want in the end floater, why we need to implement it, and that it does currently exist in some form accessible from the GUI, although there are a few issues to overcome. We want the end result to be a python function, where we can easily grab a ref to the floater for future manipulation and for easier integration with other python scripts and parts of the GUI.

Unfortunately, after looking through the docs and experimenting, there is the realization this can not be done exclusively with python.  The floating pane can be created and some of the unneeded UI elements hidden — but thats where the fun stops. List mode can be toggled on but List Order can not be, neither can a lot of the other subtle changes we tried out in the GUI in part 2. There is also the issue of pane linking we will get to a little later. So we need to figure out the initial implementation in hscript and move forward from there.  We saved our ‘scrap’ desktop in part 2 which has our preconfigured floater saved with it, so that seems like a good place to start investigating.

Navigate to the desktop file in your Houdini directory and open in your favorite text editor:

  • go to your home directory
  • look for houdiniXX.x (where XX.x is the ver number)
  • inside houdiniXX.x find ‘desktop’ folder and go inside
  • you should see scrap.desk, this is our saved desktop from part 2
  • open it in your text editor

we want to find a floater of neteditor pane type, so find ‘neteditor’, there may more than one, but the line of the one we want ends in ‘FloatingPanel’ — we know this because — well it was a floater. Copy that line into a new document. It should look something like this:

neteditor -G 0.75 -T 0.375 -K 0.3 -C 0.55 -p 0 -c 0 -o 0 -n 1 -s 3 -x 0 -w 0 -k 0 -I 0 -B 1 -D 0 -L 1 -S tree -t comments subnet none -g 0 -a 0 -y 0.5 -m e -r 2 1 -N 1 -H 0.22 -V 0.22 FloatingPanel

related to this floater you should also see immediately below it:
netviewdep -l 0 -c 0 -C 0 -e 0 -E 0 -b 0 -S 0 -s 3 FloatingPanel

and several line similar to:
netcolumns -c display,xray,select,origin,capture,bone -n OBJ FloatingPanel

if we look in our hscript reference we can see what these commands do. In short, the first ‘netviewdep’ configures options for the network graph which is irrelevant since we are not using it. The calls to ‘netcolumns’ configure what columns to toggle node flags are available for what node and network types. We will be deemphasizing this portion of the list view since our focus is selection and to a lesser degree navigation, so its fine to leave at defaults. We can ignore the other lines relating to this floater, but I did want to touch on the fact they were related and did do specific things although in this case they are not relevant.

Right away its noticeable that there’s whole lot of flags and a good chunk switched off (value ‘0’). There are flags representing alterations we may want to switch on for the FauxLiner that that weren’t obviously accessible from the GUI. The string we pulled from the desk file isn’t particularly nice to look at, really understandable nor clear. We need to figure what these flags do and break them up eliminating some that are being set to default values and causing clutter, in addition to changing the bool values of some others.

Open the hscript reference page for neteditor. Look up the ‘-S’ flag that appears with the value of ‘tree’ in our panel configuration. What?! According to the docs the only values accepted are ‘user’, ‘alpha’, ‘type’, ‘hier’, and ‘netbox’? This is partially why we didn’t start with the command as in the docs. Incomplete documentation is an issue that can be ran into now and again as hscript faces antiquation and the equivalents have not appeared in hython, along with obsoleted hscript that may not function as expected. If you look through the long list of configuration flags for the neteditor, it can be noted there are several that do not appear in the docs and vice verse. We need to add the flags from the docs we may need and test toggling the values on the undocumented ones to observe what they do. First we need a floating net editor to play with.

SHFT+ALT+t will open a text port. Create a floating pane  (differs from a floating panel as already lacks the tab UI) with dimension 600×600 named FauxLiner with  the following
pane -F -w 600 600 -n FauxLiner

the following ensures its a neteditor
pane -m neteditor FauxLiner

we can then run (filling in one or two flags in place of ‘…’ and see what happens
neteditor …. FauxLiner

this can get tricky as some changes may not be apparent unless other flags have been set (ie flags affecting list mode wont have an apparent effect if we are not in list mode currently. Likewise some flags are expected in order so keeping with the order as we had copied from the desk file makes it easier.  When adding a new flag from the docs, care should be taken as to where in the sequence of flags it is added and sometime this requires a little trial by error. In the end the sequence of flags below got the results i was looking for:

neteditor -K 0.3 -C 0.55 -p 0 -n 1 -x 0 -w 0 -k 0 -I 0 -B 1 -D 0 -L 0 -S tree  FauxLiner

Earlier, issues with pinning and linking were mentioned. We want to assign this floater an unused pane link group. For those unaware, in addition to the newer pane pinning behavior there are also pane link groups. These allow a number to be assigned to panes. All panes with the same group number move together similar to the behavior of all panes being unpinned.  This behavior tends to work nicer with some scripts in addition to a powerful way of managing a large amount of panes that can accumulate.

We don’t want the FauxLiner to get accidentally included in a group. Essentially we want it permanently pinned and unaffected via other pane navigation, by setting it to an unused group. The menu under the pin displays 1-9 as the group options. Similarly these are the same as accessible via hython. However using hscript we can set any 1 or 2 digit group number. This is great setting above ‘9’ means there would be no way to have it accidentally included via the gui or python.  To set it to ’99’ we use:

pane -l 99 FauxLiner

remember the issue during the mockup of all neteditors toggling to list mode initially once we get to  the level the floating pane was set to list or deeper? What we need is hierarchal level that above anything set in GUI. Such a level does exist and is called ‘the director’ and displayed as ‘/’. By opening the Fauxliner at the director level we not only have access to every node in the scene going deeper, but now set on a level above what can be accessed normally bypassing our list toggling pitfall! (*NOTE: an interesting side effect of having everything listed from the director downwards is being able to select the manager network nodes immediately below the director i.e. ‘/obj’ etc..) The following opens the list at ‘/’ via ‘-h /’ and is combined with the toggling off of the navigation in the pane.

pane -a 1 -A0 -h / FauxLiner

We now have a complete (and very compact) hscript that can be used to create our FauxLiner!!!
pane -F -w 600 600 -n FauxLiner
pane -m neteditor FauxLiner
pane -l 99 FauxLiner
pane -a 1 -A0 -h / FauxLiner
neteditor -K 0.3 -C 0.55 -p 0 -n 1 -x 0 -w 0 -k 0 -I 0 -B 1 -D 0 -L 0 -S tree  FauxLiner

This COULD be pasted into a .cmd file in the script path and sourced to recreate our FauxLiner, as a complete tool. But this doesn’t totally meet the objective of being accessible via python and lacks configurability.

We can formulate hscript commands as a string argument to a python function that calls hscript from python and return results. The function is appropriately named hscript and is a method of the hou module. If we look at the HOM reference “…specify multiple commands by using ‘;’ or the newline character as the separator…”.  So, we need to encapsulate each command in a python string ending with a newline ( \n ) and send it as arg to the hou.hscript() function. To keep things clean as possible, we will assign each individual line to a variable named meaningfully to the commands purpose, place them in a list, and lastly join them to a larger string to be evaluated.

# build command strings
cmd_make_floater      = ‘pane -F -w 600 600 -n  FauxLiner \n
cmd_link_pane           = ‘pane -l 99 FauxLiner \n
cmd_set_tab_type      = ‘pane -m neteditor FauxLiner \n
cmd_format_tab         = ‘pane -a 1 -A0 -h / FauxLiner \n
cmd_setup_neteditor  = ‘neteditor -K 0.3 -C 0.55 -p 0 -n 1 -x 0 -w 0 -k 0 -I 0 -B 1 -D 0 -L 0 -S tree  FauxLiner\n

# create the hscript arg string and ececute it
hscript_cmds = [cmd_make_floater,cmd_link_pane, cmd_set_tab_type, cmd_format_tab, cmd_setup_neteditor ]
hscript_string = ‘ ‘.join(hscript_cmds)
hou.hscript(hscript_string)

Now that we have our hscript nicely wrapped in hython, lets turn it into a function. We are also going to add some args for the window height and width, and the pane link group (in that rare case 99 is occupied). A check is also added to look for the FauxLiner floater already existing as since it is a flat list and the selections are global. Lastly, we find the floater we created so we may return a py ref to it. Here the finished script below.

import hou
def
fauxLiner(width=450, height=600, pane_link=99):

# check if it already exist
if hou.ui.findPaneTab(‘FauxLiner’) != None:

return None

# convert the passed numebrs to strings
width        = str(width)
height       = str(height)
pane_link = str(pane_link)

# build command strings
cmd_make_floater     = ‘pane -F -w ‘ + width + ‘ ‘ + height + ‘ -n  FauxLiner \n
cmd_link_pane           = ‘pane -l ‘ + pane_link + ‘ FauxLiner \n
cmd_set_tab_type      = ‘pane -m neteditor FauxLiner \n
cmd_format_tab         = ‘pane -a 1 -A0 -h / FauxLiner \n
cmd_setup_neteditor  = ‘neteditor -K 0.3 -C 0.55 -p 0 -n 1 -x 0 -w 0 -k 0 -I 0 -B 1 -D 0 -L 0 -S tree  FauxLiner\n

# create the hscript arg string and ececute it
hscript_cmds = [cmd_make_floater,cmd_link_pane, cmd_set_tab_type, cmd_format_tab, cmd_setup_neteditor ]
hscript_string = ‘ ‘.join(hscript_cmds)
hou.hscript(hscript_string)

 # get a py ref to the window
result = hou.ui.findPaneTab(‘FauxLiner’)

return result

FauxLiner final version in houdini 11

FauxLiner showing muli-node selction from different heirarchical levels in H11

Thats about it! We now have a functioning floating Outliner-like pane that should not disrupt other parts of Houdini’s interface! It also inherited a few nice features from the regular list view I chose to leave exposed including the filter box and the filter by type tabs on the left (which can still be stowed).

You can now delete the old scrap.desk as it no longer of use. Continue to the fourth and final part for after-thoughts, usage, caveats, and download info.

FauxLiner: part 2 — Why. (and why not.)

Node Tree/List View: The Network Editor has two notable view modes that can be toggled on. This is the first place new users tend to look for an Outliner like functionality — its close, but not quite. If you put your mouse over the network pane and then press ‘w’ followed by ‘t’, you will have a tree of your session on the left and a list of the nodes at the current select hierarchy level on the right.

h11 tree and list node view

H11 Network pane in tree/list view mode

However this mode does NOT allow us to select multiple nodes at different levels easily and leads to disappointment. The behavior is expected and does make sense and when thought about, looks like and behaves similar to a OS file browser. (*NOTE: This too fits the case since technically the hip file is an archive that can be expanded out into the filesystem — but that’s a topic for another blog..) Similar to i.e. windows explorer you can use the left tree to navigate to different levels and list contents on the right (*NOTE: actually where Explorer shows children of the selected, list view shows siblings). Since the left side is intended for navigation -multiple nodes/nets can not be selected, and since the right only shows a list relative to the selected, there is no way to multi-select nodes at different levels. If you toggled these views on, press ‘w’ and then ‘t’ to return to our default node view.

Custom List and Desktop: What we want would be similar to the list view where multiple selections are allowed, but organized similar to the tree view, displaying multiple hierarchal levels in the session — fortunately such a view does exist from with in the GUI (although not overly accessible) and this will be what the new floater is eventually based on. To get to it:

  • place mouse pointer in the network pane
  • ALT+SHFT+w to tear off a copy
  • place mouse over new copy
  • press ‘t’ to toggle list mode
  • RMB and from the popup..  List Order –> Tree
  • LMB the top icon on the far left looking like an arrow (this get rid of the columns representing the node flags)
  • since the stowbar with alignment, color swatch etc.. is only relevant to the node graph view we may want to stow this as well
  • ‘ALT+\’ will hide the network controls (not needed since we are listing everything)
  • In our final version the tab can also be hidden since this will be a separate floater specific for the FauxLiner. This can be toggled via ‘Pane Tab Operations Menu’ (the little triangle in a circle on the upper right of the pane. Pane Interface –> Pane Tabs
network pane list view. Tree List Ordered

H11 Network List mode. List Ordered as Tree

…. hmmm Now we have something that kind of looks like the Outliner. We might be tempted to save this with the Desktop and use as is.

But, there are issues:

  • its is attached to the saved desktop
  • it always opens with the desktop even when unneeded
  • there is no easy way to reopen it once the window gets closed
  • can easily interfere with pane linking/pinning behaviors
  • the current level when the settings were altered is now in list mode. So, navigating in a different network pane, we will encounter this mode toggle on
  • in general the functionality of the network graph as usual is depleted as it is somewhat tied to our custom view

But this is still a good starting point. So lets save the Desktop temporarily as ‘scrap’. From the top menu bar… Windows –> Desktops –> Save Current Desktop As.. enter ‘scrap’ (without the quotes of course) as the name, LMB save, and we should get a confirmation from Houdini. If you want to continue to use this session and Desktop as Normal. Unstow all the bars and follow the above steps resetting the options back.

HScript and Python: TDs and pipelines have taken to Python with gusto. It allows rapid development and the reuse of libraries between applications (as most major 3D apps now have a python interface).  Unlike some other 3D packages that wrapped former proprietary scripting in python, sidefx seems to have implemented it from the ground up. This is fantastic for stability and robustness but there is a speed bump that pops up frequently…. hython (Houdini’s python) allows us to deal with nodes as programming objects and gives access to many newer features and options unavailable from hscript (Houdini’s former primary scripting language). On the other side of the coin,hscript allows us to deal with the session in terms similar to a filesystem which is often useful (I found particularly so when render farm processing) and still gives access to ALOT of options and areas not yet implemented in hython and many that likely will never be. (*NOTE: a down side of this particular point is some hscript no longer really applies as it was written before the 9.x UI overhaul)

Because of the reasons above, TDs VERY often find themselves mixing the two languages using a variety of techniques, the most common using the Houdini provided functions which allow the calling of one language from the other.  Almost all sizable projects in either language will have to employ such strategies as well as tasks which involve delving into less than often manipulated aspects of the GUI — The FauxLiner falls into the latter scenario.

In the next session we will work out how to get a functioning FauxLiner.

FauxLiner: part 1 – What.

Often the transition from another 3D application to the procedural world of Houdini can be bumpy for those who have been accustomed to working largely in another single CG program.  One reason is that different applications have different strong points and offer varying methodologies to get to similar rendered end results in the final frame, and many artist may end up viewing the general concepts in 3D CG as filtered through the specific program they had practiced in.  Although the first 500 hrs in any program is always the hardest, for those who may have been using another app for 5 or even 10 or more years, those first 500 hours are a distant memory and a drastically different interface can be alienating and have a 3D app like Houdini dismissed as frustrating because familiar menus and GUIs may not be presented in the same way as accustomed to.

These days if an artist knows only one app, its likely going to be Autodesk’s Maya.  Maya has its strong points but very few would argue proceduralism and the hypergraph as an interactive node/DAG as amongst them.  The hypergraph has long been an outdated node editor and lack simple functionality such as an easy way to quickly wire dependency nodes. While it seems this will be addressed by Autodesk in the near future (hopefully), in the 10 some what odd years since its introduction, for similar functionality with equally limited interaction, many have become accustomed to the Outliner as a central part of daily workflow, scene navigation, and object selection.

This series of posts will look closer at a little GUI floater I affectionately call The “FauxLiner” — an Outliner-like navigation and selection interface. We are going to look at why it is constructed the way it is, the process of how to derive the actual script (which will hopefully hint to how to make other GUIs using similar techniques), and caveats in its use as well as similarities and differences with the Outliner presented in Maya. While I firmly believe that trying to make one CG aplication present itself in terms of another purely for the sake of reducing a learning curve wiil result in losing much of the power and robustness present natively and being side-stepped, in this case, it does have a couple of strong points:

  • An Outliner-like GUI will make the transition easier and less alienating (as its so central to many artists workflow)
  • Although it presents no way to show or manipulate relationships beyond hierarchical, Maya’s Outliner does make an adept selection tool where objects from multiple levels of the heirarchy can be represented and selcted in a single location.
  • The above in terms of Houdini would be extremely useful when creating bundles or processing node selections via scipts, where its easier not to open multiple network panes.

So while I discourage the use of FauxLiner as a way to avoid learning how to deal with the more powerful and controllable procedural node interface, it does make a good example of a GUI that may be needed to move a group of artists into unfamiliar territory easier, as well as adding a powerful selection system to our tool arsenal. Lets move forward and look at why we will be constructing this Floater in the manner outlined in part 3. Onward to part 2 -Why.