Filter AOVs
Hi team,
I’ve always found it slow and frustrating using the default LayerContactSheet node inside nuke. Often you will get exrs with dozens of layers and they never line up in a pleasant way. Hoping to come up with a better way of visualizinng layers I created this tool.
download here:
https://www.nukepedia.com/gizmos/other/filter_aovs
In the above image we see Viewer1 is looking at our filtered selection (any layer containing ‘Lighting_A1’, or ‘lighting’) and in viewer2 we see the default result of a LayerContactSheet. Lets take a look at the user controls before diving in to whats going on internally.
-- Controls Tab --
scale - controls the overall size of the final contactsheet
AOV Type - This selects the preset type
Custom - for quick filtering without adjusting the presets
Update Available AOVs - runs code that displays the all the aovs that match the user filtering
Remove Empty Channels - If there is no RGB information for an AOV on the current frame it is removed from viewing
View Channels with Values - switches between seeing the empty channels and removing them
Unlock Presets - locks and unlocks the Presets tab (wanted it to be a conscious effort to change)
-- Presets Tab --
Search Type - choose between the two search methodologies. Will also switch which presets are available.
—Contains - converts all the user and aov text to lowercase and compares if the user text is in any of the aovs.
—Regex - uses Regular expressions to allow for more advanced matching
Various Text Input Knobs - the names for these are simply suggestions based on how I would use them. You can add whatever filtering you like. Feel free to change the labels as you see fit. Don't change the names of the knobs though the code is looking for the specific names
Looking at the Controls Tab there are two main areas to dig into. the ‘Update Available AOVs’ button and the ‘Remove Empty Channels’ button. For now let us focus just on the ‘Update Available AOVs’
Taking a look there are some usefu helper functions for Update Available AOVs’.
import re #----------------------------- #----------------------------- ####### Functions for the Update Availabe AOVs Button #----------------------------- ##### #creates a set of all the channels that the given node has def autoComp(node): channels = node.channels() #is there not a way to just look for the layers?? layers = list( set([c.split('.')[0] for c in channels]) ) return layers #----------------------------- ##### #based on user inputs looks for aovs #0 uses the in keyword to check if the user aovs exist in the input aovs #1 uses the regex modules search method to check if the user aovs exist in the input aovs def inputMatchAOV(aov): searchType = nuke.thisNode()['searchType'].getValue() #0 is contatins 1 is regex aovType = nuke.thisNode()['type'].value() if searchType == 0: aov = aov.lower() # for simplicity I've diced to ignore case sensitivity searchKnob = 'preset' + aovType searchString = nuke.thisNode()[searchKnob].value().lower() if aov in searchString: return 1 else: return 0 else: searchKnob = aovType searchKnob = 'regexPreset' + searchKnob searchString = nuke.thisNode()[searchKnob].value() reg = re.search(searchString, aov) if bool(reg): return 1 else: return 0
The first function autoComp():
is a direct reuse of the code found in the developer guides. Have a read through if you would like more information.
https://learn.foundry.com/nuke/developers/90/pythondevguide/channels.html
The second function takes in an aov(type string) to match to.
First we are checking our user inputs to see what methodology of comparison(‘in’ vs ‘re.search’) we are doing and what preset type (‘custom’, ‘light’, ‘material’, ‘data’)we are checking against. Then we return 0 or 1 if the comparison is successful.
Next let’s take a look how we are using these functions to generate something useful. But first let’s take a look inside the FilterAOVs group.
There are two nodes with custom names (‘squared’ in blue). These will come in handy in the next code block
#----------------------------- #----------------------------- ''' #Main code block #1 Set our context inside the group. #2 Get a list of all aovs that are entering the group. #3 Cleanup any previous nodes created inside the group #4 Get a list of all aovs that exist and match the user input #5 Keep only the aovs that are in the match list ''' #1 Get the group name and set the context to be working inside the group gizmo = nuke.thisNode() thisGroup = nuke.thisNode().name() with nuke.toNode(thisGroup) as parent: nodeAOV = nuke.toNode('startAOV') aovList = list(autoComp(nodeAOV)) #2 merge = nuke.toNode('MergeAOV') startList = nuke.toNode('startList') nukescripts.clear_selection_recursive() matchList =[] #3 cleanup remList = nuke.allNodes('Remove') for n in remList: nuke.delete(n) for input in range(1, merge.inputs()): merge.setInput(input, None) #4 create a new list for all the channels that match the the user presets if parent['type'].getValue() == 0: matchList = aovList else: for i in aovList: if inputMatchAOV(i) == 1: matchList.append(i) #5 creates a remove (keep) node for each layer for i in matchList: remNode = nuke.createNode('Remove', inpanel=False,) remNode.connectInput(0,nodeAOV) remNode['operation'].setValue('keep') remNode['channels'].setValue(i) merge.connectInput((matchList.index(i)+4), remNode) # the +4 is so we start on the merge nodes A1 pipe and incriment up from there nukescripts.clear_selection_recursive() #leaveGroup and flip the switch to be looking at all channels available gizmo['switch'].setValue(0) #####