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()