Last active
September 18, 2025 01:49
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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