setRotoLifeTime()
I recently came across this script, https://www.nukepedia.com/python/nodegraph/lifetimeroto . I really liked the idea but found it were multiple shape objects in the curve knob. I also wanted to add some functionality to be able to additional layers nested inside the root. This is the full code. use it as you see fit!
#::::::::::::::::::::::::::::
#:::: SET ROTO LIFETIME ::::
#::::::::::::::::::::::::::::
# Robert Matier
# Version: 1.0.0
# Last Updated: 2025/02/03
# Looks at all selected nodes if nodes Class is 'Roto' or 'RotoPaint'
# Recursively look through all the objects in the nodes curve knob
# if they are Shape we check if there is animation on that node
# if there is animation we set the lifetime attribute to match the animation
import nuke.rotopaint as rp
#----parseLayer----
# pass in a starting curve knob object (root), a list of names (noe at start), and a string tp track the parents (none at start)
# recursively gather all shapes and returns a list with all their names
def parseLayer(rootLayer, listNames, parents):
for rotoObject in rootLayer:
#if we are looking at a layer we need to modify the parent name and go a level deeper to see if there are shapes
if isinstance(rotoObject, rp.Layer):
curName = rotoObject.name
parentNames = parents + curName + '/'
listNames = parseLayer(rotoObject, listNames, parentNames)
#we are ignoring strokes
elif isinstance(rotoObject, rp.Stroke):
continue
else:
# if the shape has parrents we need to add them to the name
if parents:
newObject = parents + rotoObject.name
listNames.append(newObject)
# we are at the root layer and there are no parent layers
else:
listNames.append(rotoObject.name)
return listNames
#----setRotoLife----
# Takes a user selection of nodes and actions on nodes with Class 'Roto' or 'RotoPaint'
# Looks at the nodes curve knob and using the parseLayer() iterates through a list of all the available shape objects
# At each shape object gets all the keyframes storing the lowest and highest values
# sets the objects lifetime attributes based on these values.
def setRotoLifeTime():
selNodes = nuke.selectedNodes()
if len(selNodes) == 0:
nuke.message('No nodes selected, please select Roto or RotoPaint nodes.')
return
### find selected roto shapes keyframes
for node in selNodes:
if node.Class() not in ('Roto','RotoPaint'):
continue
elementNames = []
parentNames = ''
cKnob = node['curves']
root = cKnob.rootLayer
listNames = parseLayer(root, elementNames, parentNames)
for name in listNames:
currentObject = cKnob.toElement(name)
keyFrame = currentObject[0].center.getControlPointKeyTimes()
keyFrames = [int(i) for i in keyFrame]
low = (min(keyFrames))
high = (max(keyFrames))
attrs = currentObject.getAttributes()
if low != high:
attrs.set('ltn', low) #lifetime_start
attrs.set('ltm', high)#lifetime_end
attrs.set('ltt', 4) #lifetime_type
setRotoLifeTime()