NukeX Node Creator in Python
- Max Austin
- Jul 6, 2024
- 3 min read
Updated: Jul 10, 2024
TLDR :
Create an artist friendly interface to make NukeX exclusive nodes in Nuke.
Access to NukeX can sometimes be scarce and when you just need it to create a Motion Blur node with a specific shutter speed or more samples, it can be quite a hassle. For the past few years I've been creating these NukeX nodes in Nuke with whatever properties I want using a Python command. For example,
nuke.nodes.MotionBlur( shutterTime = 0.75, shutterSamples = 8 )
However, not everyone feels comfortable enough to open the script editor, and it can take up precious time typing an elaborate Python command, so I wanted to offer a simpler solution.
Below is the panel created by running the script. There are currently 3 supported nodes in the main dropdown menu and the UI updates to fill with the correct properties using the knobChanged callback.

The resulting node created from the above panel.

import nukescripts
import nuke
# The following defines a new class called NodeSelectionPanel.
class NodeSelectionPanel( nukescripts.PythonPanel ):
# The following function initializes and adds the knobs to the panel
def __init__( self ):
nukescripts.PythonPanel.__init__( self, "X Node Creator" )
#Initializing node selection knob
self.node_list = nuke.Enumeration_Knob("node_list", "<b>Node List</b>", ['Motion Blur', 'Smart Vector', 'Vector Distort'] )
self.text = nuke.Text_Knob('')
#Initializing Motion Blur Knobs
self.shutter = nuke.Int_Knob("shutter", "Shutter Samples" )
self.shutter_time = nuke.Double_Knob("shutter_time", "Shutter Time" )
self.motion = nuke.Enumeration_Knob("motion", "Motion", ['Regularized', 'Local'] )
self.vector_detail = nuke.Double_Knob("vector_detail", "Vector Detail" )
self.moblur_filter = nuke.Enumeration_Knob("moblur_filter", "Filter", ['Bilinear', 'Lanczos4', 'Lanczos6'] )
self.moblur_matte = nuke.Enumeration_Knob("moblur_matte", "Matte", ['None', 'Source Alpha', 'Source Inverted Alpha', 'Matte Luminance', 'Matte Inverted Luminance', 'Matte Alpha', 'Matte Inverted Alpha'] )
#Initializing Smart Vector Knobs
self.vectDetail = nuke.Double_Knob("vectDetail", "Vector Detail" )
self.strength = nuke.Double_Knob("strength", "Strength" )
self.sv_matte = nuke.Enumeration_Knob("moblur_matte", "Matte", ['None', 'Source Alpha', 'Source Inverted Alpha', 'Matte Luminance', 'Matte Inverted Luminance', 'Matte Alpha', 'Matte Inverted Alpha'] )
#Initializing Vector Distort Knobs
#self.refFrame = nuke.Int_Knob('refFrame', 'Reference Frame')
self.ref_text = nuke.Text_Knob('Node must be created on reference frame.')
self.hold = nuke.Boolean_Knob('hold', 'Hold Frame')
self.fr_dist = nuke.Enumeration_Knob("fr_dist", "Frame Distance", ['1 frame', '2 frames', '4 frames', '8 frames', '16 frames', '32 frames', '64 frames'] )
self.output = nuke.Enumeration_Knob("output", "Output", ['warped src', 'st-map', 'st-map inverse'] )
self.blur = nuke.Double_Knob("blur", "Blur Size" )
self.vd_filter = nuke.Enumeration_Knob("vd_filter", "Filter", ['impulse', 'cubic', 'Keys', 'Simon', 'Rifman', 'Mitchell', 'Parzen', 'notch', 'Lanczos4', 'Lanczos6', 'sinc4'] )
self.end_text = nuke.Text_Knob('')
#Adding Node selection knob
self.addKnob( self.node_list )
self.node_list.setValue( 0 )
self.addKnob( self.text )
#knobs for Motion Blur
self.addKnob( self.shutter )
self.shutter.setValue( 4 )
self.addKnob( self.shutter_time )
self.shutter_time.setValue( 0.5 )
self.addKnob( self.motion )
self.motion.setValue( 1 )
self.addKnob( self.vector_detail )
self.vector_detail.setValue( 0.5 )
self.addKnob( self.moblur_filter )
self.moblur_filter.setValue( 0 )
self.addKnob( self.moblur_matte )
self.moblur_matte.setValue( 0 )
#knobs for Smart Vector
self.addKnob( self.vectDetail )
self.vectDetail.setValue( 1 )
self.addKnob( self.strength )
self.strength.setValue( 1.5 )
self.strength.setRange( 0, 2.5 )
self.addKnob( self.sv_matte )
self.sv_matte.setValue( 0 )
#knobs for Vector Distort
#self.addKnob( self.refFrame )
#self.refFrame.setValue( 1 )
self.addKnob( self.ref_text )
self.addKnob( self.hold )
self.hold.setValue( True )
self.addKnob( self.fr_dist )
self.fr_dist.setValue( 0 )
self.addKnob( self.output )
self.output.setValue( 0 )
self.addKnob( self.blur )
self.blur.setValue( 0 )
self.blur.setRange(0, 32)
self.addKnob( self.vd_filter )
self.vd_filter.setValue( 1 )
self.addKnob( self.end_text )
#function to read a knob value in real time
def knobChanged(self, knob):
nodeValue = self.node_list.value()
print( nodeValue )
self.node_list.setValue( nodeValue )
#statement to display certain knobs only for certain nodes
if nodeValue == 'Motion Blur':
self.shutter.setVisible( True )
self.shutter_time.setVisible( True )
self.motion.setVisible( True )
self.vector_detail.setVisible( True )
self.moblur_filter.setVisible( True )
self.moblur_matte.setVisible( True )
else :
self.shutter.setVisible( False )
self.shutter_time.setVisible( False )
self.motion.setVisible( False )
self.vector_detail.setVisible( False )
self.moblur_filter.setVisible( False )
self.moblur_matte.setVisible( False )
if nodeValue == 'Smart Vector':
self.vectDetail.setVisible( True )
self.strength.setVisible( True )
self.sv_matte.setVisible( True )
else :
self.vectDetail.setVisible( False )
self.strength.setVisible( False )
self.sv_matte.setVisible( False )
if nodeValue == 'Vector Distort':
#self.refFrame.setVisible( True )
self.ref_text.setVisible( True )
self.hold.setVisible( True )
self.fr_dist.setVisible( True )
self.output.setVisible( True )
self.blur.setVisible( True )
self.vd_filter.setVisible( True )
else :
#self.refFrame.setVisible( False )
self.ref_text.setVisible( False )
self.hold.setVisible( False )
self.fr_dist.setVisible( False )
self.output.setVisible( False )
self.blur.setVisible( False )
self.vd_filter.setVisible( False )
#Function to show the panel and create the node based off user selections
def showPanel():
n = NodeSelectionPanel()
if n.showModalDialog():
print( n.node_list.getValue())
if n.node_list.getValue() == 0:
nuke.nodes.MotionBlur( shutterSamples = n.shutter.getValue(), shutterTime = n.shutter_time.getValue(), motionEstimation = n.motion.getValue(), vectorDetailReg = n.vector_detail.getValue(), resampleType = n.moblur_filter.getValue(), matteChannel = n.moblur_matte.getValue() )
if n.node_list.getValue() == 1:
nuke.nodes.SmartVector( vectorDetailReg = n.vectDetail.getValue(), vectorDetailLocal = n.vectDetail.getValue(), strengthReg = n.strength.getValue(), matteChannel = n.sv_matte.getValue() )
if n.node_list.getValue() == 2:
nuke.nodes.VectorDistort( holdFrame = n.hold.getValue(), frameDistance = n.fr_dist.getValue(), outputMode = n.output.getValue(), blurSize = n.blur.getValue(), imageFilter = n.vd_filter.getValue() )
The last step was making this script easily accessible so I created a menu called "Custom Tools" and added the script there.

The following is the python added to the menu.py file found in the .nuke folder.
#NukeX Node Creator
import nukeX_node_creator
nuke.menu("Nuke").addMenu("Custom Tools").addCommand("NukeX Node Creator", "nukeX_node_creator.showPanel()")
コメント