Skip to content

Instantly share code, notes, and snippets.

@artandmath
Last active September 18, 2025 01:49
Show Gist options
  • Select an option

  • Save artandmath/df19719b415a866ddc413fe327657942 to your computer and use it in GitHub Desktop.

Select an option

Save artandmath/df19719b415a866ddc413fe327657942 to your computer and use it in GitHub Desktop.
bakeSelectedNodes() bakes knob expressions and updates node labels to indicate which nodes the expressions were referencing. Can be useful to speed up sticky nukescripts.
import nuke
import re
def bakeCurve(curve, first, last, inc):
for f in range(first, last + 1, inc):
curve.setKey(f, curve.evaluate(f))
curve.setExpression('curve')
def getCurves(knob, views):
curves = []
for v in views:
curves.extend(knob.animations(v))
return curves
def extractSourceNodesFromExpression(expression):
"""Extract node names referenced in the expression"""
sourceNodes = set()
# Pattern to match node references like "NodeName.knobname" or "NodeName['knobname']"
# This covers most common Nuke expression patterns
patterns = [
r'([a-zA-Z_][a-zA-Z0-9_]*)\.', # NodeName.knob
r'([a-zA-Z_][a-zA-Z0-9_]*)\[', # NodeName[knob]
r'nuke\.toNode\(["\']([^"\']+)["\']', # nuke.toNode("NodeName")
]
for pattern in patterns:
matches = re.findall(pattern, expression)
for match in matches:
# Check if this is actually a node that exists
try:
node = nuke.toNode(match)
if node:
sourceNodes.add(match)
except:
pass # Not a valid node reference
return list(sourceNodes)
def bakeExpressionKnobs(node, first, last, inc, views):
expKnobs = [k for k in node.knobs().values() if k.hasExpression()]
allCurves = []
allSourceNodes = set()
# Collect expressions and find source nodes before baking
for k in expKnobs:
expression = k.toScript()
sourceNodes = extractSourceNodesFromExpression(expression)
allSourceNodes.update(sourceNodes)
for k in expKnobs:
allCurves += getCurves(k, views)
for c in allCurves:
bakeCurve(c, first, last, inc)
return list(allSourceNodes)
def updateNodeLabel(node, sourceNodes):
"""Update the node's label to show which source nodes expressions were baked from"""
if not sourceNodes:
return
# Get existing label
currentLabel = node['label'].value()
# Create source nodes info
sourceInfo = "Baked from: " + ", ".join(sorted(sourceNodes))
# Combine with existing label
if currentLabel:
newLabel = currentLabel + "\n" + sourceInfo
else:
newLabel = sourceInfo
node['label'].setValue(newLabel)
def bakeSelectedNodes():
ret = nuke.getFramesAndViews('Bake curves in selected nodes?', '%s-%s' % (nuke.root().firstFrame(), nuke.root().lastFrame()))
if not ret:
return
fRange = nuke.FrameRange(ret[0])
views = ret[1]
processedNodes = []
for n in nuke.selectedNodes():
sourceNodes = bakeExpressionKnobs(n, fRange.first(), fRange.last(), fRange.increment(), views)
if sourceNodes: # Only update label if source nodes were found
updateNodeLabel(n, sourceNodes)
processedNodes.append(n.name())
print("Node '{}' baked expressions from: {}".format(n.name(), ", ".join(sourceNodes)))
# Print summary
if processedNodes:
print("Processed {} nodes with expressions".format(len(processedNodes)))
else:
print("No expressions found in selected nodes.")
# Usage: Select your nodes in the node graph, then run bakeSelectedNodes()
bakeSelectedNodes()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment