Toggle null visibility in viewport (script?)

   7876   26   5
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Hey guys and gals,

We're using Houdini on a job so are jumping head first in to animation.

Quick question though as I can't find an answer anywhere on this.



In Soft and Maya a commonly used behaviour is to toggle the visibility of all null objects in the viewport. I can't find a way to assign a hotkey to this behaviour, or indeed a script that does it (I cannot script).

This is used during the animation process probably as often as the Move and Key hotkeys, so we're missing it at the moment in our workflow.


Work arounds have included -

- excluding a (smart) bundle of 'null objects' in the optimize-visibility path box using the * ^@bundle (this works, but if you add a new null to the bundle it doesn't refresh in the view, so you have to make a new bundle)

- using the 'viewport isolator' node (this is nearly a good solution, but with High Quality lighting on it seems to erroneously display the nulls within the silhouette of the meshes)

- having two 'scene view' panels side by side, allowing for different options for each view. This option would be most ideal because it would give flexibility for a host of other options like lighting and textures etc... Problem with this is that playback speeds are cut in half, understandably(?). So with multiple chars and an env this is not a solution unfortunately.

If anyone else can offer a solution (ideally) or workaround (workable in the short term) to this, it would be highly appreciated.


The simplest solution would be if the 'Nulls' flag (and others) were available to assign to a hotkey in the hotkey editor. But this is not the case.


Answers on a postcard?!

Thanks a lot

Nick

Attachments:
Screenshot 2020-12-17 172653.jpg (15.6 KB)

User Avatar
Member
292 posts
Joined: July 2013
Offline
You can set different options for what to show during playback, it's the button beneath the one that has the fly-out in the screenshot.

Maybe that helps.
Edited by Jonathan de Blok - Dec. 18, 2020 12:08:56
More code, less clicks.
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Thanks for the suggestion. Although this is useful, it's not really what I'm looking for.

It needs to be a toggle functionality so one can view with or without the nulls when orbiting the rig in the viewport.

Plus it doesn't work when scrubbing the timeline, only playing.


Thanks
Edited by nicksmalley - Dec. 18, 2020 12:53:06
User Avatar
Member
292 posts
Joined: July 2013
Offline
You could set one of the two viewport to hide everything on playback. So that should fix the 50% performance drop.

But what your really after is a simple python script that gathers all nulls and toggles the display flag. I would like to have this feature too so I'll write something for it I guess it's less then 10 lines of code, check back here in an hour or so..
More code, less clicks.
User Avatar
Member
292 posts
Joined: July 2013
Offline
import hou

def toggleNulls(state, root=hou.node("/obj"), types=["null"]):
    for node in filter(lambda node: node.type().name() in types, root.allSubChildren(recurse_in_locked_nodes=False)): node.setDisplayFlag(state) 
            

toggleNulls(True)

Here is a function that will toggle all nulls on/off even in nested subnets etc.

Some examples:

#toggle all nulls off globally:
toggleNulls(False)


#toggle all nulls on globally:
toggleNulls(True)

#toggle all nuls in someRigSubnet to on:
toggleNulls(False, root=hou.node(/obj/someRigSubnet")

#toggle all nuls in someRigSubnet to off again:
toggleNulls(False, root=hou.node(/obj/someRigSubnet")

#toggle all nulls and bones globally:
toggleNulls(False, types=["null","bone"])


You can add this to a shelf (context menu-> new tools, paste code in the script tab) and then in the same dialog's hotkey tab you can assign a hot key.
Edited by Jonathan de Blok - Dec. 18, 2020 14:08:00
More code, less clicks.
User Avatar
Member
8173 posts
Joined: Sept. 2011
Offline
Jonathan de Blok
Here is a function that will toggle all nulls on/off even in nested subnets etc.

Note that this script modifies the scene, and will fill up the undoes.

Modifying scene viewer object visibility filter with a script would leave the scene untouched.

Unfortunately, I don't see any methods in the hou module for scripting the display options on the right sidebar. The menu will have to do for now.

I suggest submitting an RFE to Sidefx for this feature, as all aspects of the interface should be scriptable.
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Thanks a lot for your replies guys.

The script you made Jonathan would suffice for simple scenes, so that’s definitely a brute force work around to have in mind for future suitable scenarios.

But unfortunately within our locked HDAs are a lot of different nulls that are a combination of on/off and of which some are linked to other promoted parameters etc.. so blanket switching them all on or off isn’t quite what I’m after.

Jsmack, thanks for your reply. Yes it seems like every other part of the interface is assignable apart from that bit! I shall submit a request.

Hopefully this is something very simple to implement. The icing on the cake would be if the visibility of nulls flag was separate between each viewport, as most animators need to have a ‘clean’ camera view whilst at the same time working with a rig in persp view.

When one is hiding and showing nulls on a rig hundreds of times a day, the menu and check box method becomes very arduous!

Thanks

Nick
User Avatar
Member
192 posts
Joined: Oct. 2018
Offline
There's an hscript function to hide those in the scene viewer, so you can use hou.hscript() to run it:

import toolutils

try :
    viewername = None
    desktop = hou.ui.curDesktop().name()
    pane = toolutils.activePane(kwargs).name()
    views = hou.hscript("viewls")[0].split("\n")
    
    for view in views :
        if (desktop in view) and (pane in view) :
            viewername = view.split(" ")[0]
    
    if viewername :
        hou.hscript( "vieweroption -V '-null' '%s'" % (viewername) )    
except :
    print "No scene view open."
Edited by krueger - Dec. 18, 2020 16:55:56
User Avatar
Member
292 posts
Joined: July 2013
Offline
mkps
There's an hscript function to hide those in the scene viewer, so you can use hou.hscript() to run it:

import toolutils

try :
    viewername = None
    desktop = hou.ui.curDesktop().name()
    pane = toolutils.activePane(kwargs).name()
    views = hou.hscript("viewls")[0].split("\n")
    
    for view in views :
        if (desktop in view) and (pane in view) :
            viewername = view.split(" ")[0]
    
    if viewername :
        hou.hscript( "vieweroption -V '-null' '%s'" % (viewername) )    
except :
    print "No scene view open."


Nice find! And this way it's a per viewport setting as well.
More code, less clicks.
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Hey mkps, thanks for that. I'm not sure how to implement that into a script button to add onto my shelf, and all the clever people in the company have gone home for xmas....

Would it be possible to briefly guide me as to how I might use this?

I'm really not a scripty person and am v new to Houdini.

Sorry!

Thanks

Nick
User Avatar
Member
192 posts
Joined: Oct. 2018
Offline
You're trying to put it on a shelf or somewhere else like in a digital asset?

If it's just a shelf button, you right click on a shelf > New Tool, then paste that code in the Script tab and make sure it's set to python script language.
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Ah yes, I had it set to Hscript. Told you I didin't know what I was doing

Thank you, although it doesn't seem to toggle the nulls back on again, it just sets the flag to off.

Is this something that can be part of the same script? So when it's run again it has the opposite effect.

It would be more streamlined in terms of usage if it wasn't a different script/hotkey to turn them back on.

Thanks so much for your help.

Nick
User Avatar
Member
192 posts
Joined: Oct. 2018
Offline
nicksmalley
Ah yes, I had it set to Hscript. Told you I didin't know what I was doing

Thank you, although it doesn't seem to toggle the nulls back on again, it just sets the flag to off.

Is this something that can be part of the same script? So when it's run again it has the opposite effect.

It would be more streamlined in terms of usage if it wasn't a different script/hotkey to turn them back on.

Thanks so much for your help.

Nick

I'll look to see if there's a way to test if the nulls are/aren't visible, then it could be modified to toggle them on/off. Other than that though, it could be wrapped up into a function where you tell it to show/hide.
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Amazing, thanks a lot. Muchly appreciated.

It's the small things like this that we use a lot when animating. So moving to Houdini for animation on a more permanent basis will require a solution for these little things.

Thanks!

Nick
User Avatar
Member
192 posts
Joined: Oct. 2018
Offline
A quick look around I didn't see a function to test if it was on or off, but maybe someone else more familiar with hscript would know. The alternative would be to store whether you toggle it on/off using the shelf tool in a houdini session variable, so something like this would work as a toggle.

def toggleNulls():
    import toolutils
    
    # Check to see if the nulls were toggled already.
    if "nullsVisible" in dir(hou.session) :
        visible = hou.session.nullsVisible
    else :
        visible = True
        hou.session.nullsVisible = visible
    
    try :
        viewername = None
        desktop = hou.ui.curDesktop().name()
        pane = toolutils.activePane(kwargs).name()
        views = hou.hscript("viewls -n")[0].split("\n")
        
        # Find the viewer name for hscript.
        for view in views :
            if (desktop in view) and (pane in view) :
                viewername = view
        
        if viewername :
            if visible :
                hou.hscript( "vieweroption -V '-null' '%s'" % (viewername) )
            else :
                hou.hscript( "vieweroption -V '+null' '%s'" % (viewername) )
            
            # Change the stored variable.
            hou.session.nullsVisible = not visible
    except :
        print "No scene view open."

toggleNulls()

You can also assign a hotkey to any of your shelf tools too so you can do that for this if you want.
Edited by krueger - Dec. 18, 2020 17:53:20
User Avatar
Member
292 posts
Joined: July 2013
Offline
To make it a toggle using the hscript method will probably require setting a variable in the session or something similar to store what action it did last time. When run again it will simply do the opposite of that.

hou.session.show_nulls=True

Etc..

(because I don't think there is a way to read the current setting)
Edited by Jonathan de Blok - Dec. 18, 2020 17:55:26
More code, less clicks.
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Thanks guys, sounds like storing a scene variable could well be the answer.

I’ll try it out when I log on tomorrow.

Will report back if I need my hand held a little longer crossing the road.

Again, thanks a lot.

Nick
User Avatar
Member
192 posts
Joined: Oct. 2018
Offline
This one is cleaned up a little bit, also adding the option to run over every scene view or just the active one. Adding a hotkey for the scene viewer will make it work on whichever scene view your mouse is over too.

def toggleNulls(toggleAllViewers=True):
    import toolutils
    
    # Check to see if the nulls were toggled already.
    if "nullsVisible" in dir(hou.session) :
        visible = hou.session.nullsVisible
    else :
        visible = True
        hou.session.nullsVisible = visible
    
    try :
        desktop = hou.ui.curDesktop().name()
        pane = toolutils.activePane(kwargs).name()
        views = hou.hscript("viewls -n")[0].split("\n")
        if visible :
            toggle = "-"
        else :
            toggle = "+"
        
        # Toggle viewers
        if toggleAllViewers :
            for view in views :
                hou.hscript( "vieweroption -V '%snull' '%s'" % (toggle, view) )
        else :
            # Find the viewer name for hscript.
            for view in views :
                if (desktop in view) and (".%s." % (pane) in view) :
                    hou.hscript( "vieweroption -V '%snull' '%s'" % (toggle, view) )
                
        # Change the stored variable.
        hou.session.nullsVisible = not visible
    except :
        print "No scene view open."

# Toggle current viewer
toggleNulls(toggleAllViewers=False)

# Toggle all viewers
#toggleNulls()
User Avatar
Member
8 posts
Joined: Dec. 2020
Offline
Ah that is fantastic! I know it’ll make the animators here very happy.

Be great if they whacked this in as a default viewport option as I’m sure every animator will go searching for this.

Thank you for your time, effort and expertise.

I have a feeling this won’t be the last time someone clevererer will have to make a script for me

Nick
User Avatar
Member
192 posts
Joined: Oct. 2018
Offline
No problem.
  • Quick Links