I am integrating a tool I made that applies tracking data from a Tracker node to a Roto node. It does this by creating the node, then linking each corresponding value. The tool as a standalone works perfectly fine. It creates the Roto node and applies the data appropriately, This is the most up-to-date version of the standalone tool.
The problem I am currently facing is I'm adding it to a Python Panel that I created to globally control the motionblur/samples in any or all Roto, Transform, and Scanline Render nodes inside your script. That also works fine. I am wanting to develop that control panel into a set of tools that I can quickly access. I am adding the standalone tool as a separate .py file and importing it to the "Motion Blur Control Panel", creating an instance, then adding the tool to the panel. That all works fine, it adds it to the panel and I can fiddle with the controls. The problem arises when it comes to generating the Roto node. The script will generate the node and link all the values as intended. But, it messes up the Roto node and adds extra controls like stereo offset, and adding paint controls to the top of the Viewer. Now, if I click onto the select tool, it'll disappear and appear as a normal Roto node. But, if I try to make a shape or select the root in the Roto node, the expression link breaks, almost like the node is resetting.
I know Nuke can be a little buggy, so I am chalking this up to a problem with the way the pythonpanel creates the Roto node.
Example of how the panel is supposed to look
import nukeclass trackToRotoClass: def __init__(self): # Control knobs # rest of code self.create_roto = nuke.PyScript_Knob('create_roto', 'create') def create_knobs(self, panel_instance): # Add knobs # rest of code panel_instance.addKnob(self.create_roto) def knobChanged(self, knob): # Handle changes in the UI trigger_TTR = {self.create_roto} if knob in trigger_TTR: self.link_roto() def link_roto(self): tracks = nuke.selectedNodes() if not tracks: nuke.message('Please select a Tracker node before executing!') return if len(tracks) != 1 or tracks[0].Class() != "Tracker4": nuke.message('Please select exactly one Tracker node before executing!') return tracker = tracks[0] nuke.selectAll() nuke.invertSelection() for tracker in tracks: if tracker.Class() == "Tracker4": # Create Roto node roto = nuke.createNode("Roto") roto.setXYpos(tracker.xpos() + 50, tracker.ypos() + 50) # Set input to the tracker node roto.setInput(0, None) link_method = self.which.value() # Link values if bool == true translate = self.translate.value() rotate = self.rotate.value() scale = self.scale.value() center = translate or rotate or scale # Checks if the link_method is live-linked or baked if link_method == 'live-link': if translate: roto['translate'].setExpression(tracker.name() +".translate") if rotate: roto['rotate'].setExpression(tracker.name() +".rotate") if scale: roto['scale'].setExpression(tracker.name() +".scale") if center: roto['center'].setExpression(tracker.name() +".center") elif link_method == 'baked': roto['translate'].fromScript(tracker['translate'].toScript()) roto['rotate'].fromScript(tracker['rotate'].toScript()) roto['scale'].fromScript(tracker['scale'].toScript()) roto['center'].fromScript(tracker['center'].toScript()) roto['label'].setValue("Baked: " + tracker.name()) else: nuke.message('Please select a Tracker node before executing!')
This is also the way I am implementing it into the python panel, the code is condensed to pretty much just include the functions for the track to roto tool:
import nukeimport nukescriptsfrom tracktoroto import trackToRotoClassclass MBControlPanel(nukescripts.PythonPanel): def __init__(self): nukescripts.PythonPanel.__init__(self, 'Global Control Panel', 'NukePanel.MBCP') # Create instances of the MB controls self.trackroto_instance = trackToRotoClass() self.addKnob(self.div5) self.div5.setFlag(nuke.STARTLINE) # Add Track to Roto knobs self.trackroto_instance.create_knobs(self) self.addKnob(self.div6) self.div6.setFlag(nuke.STARTLINE) def knobChanged(self, knob): # Handle changes in the UI # Use knobChanged functions inside the relevant .py scripts to trigger changes in the control panel self.trackroto_instance.knobChanged(knob)
I am pretty new to coding, I don't have a ton of Python experience, any help would be appreciated!
I have tried using a RotoPaint node instead, and the same happens. I did try adding a Blur node and linking the translate to the size knob, and that worked, but I suspect since the two nodes aren't comparable that doesn't really help.
I have also tried adding the entire link_roto script to the PyScript Knob, the same way it is usually done with the PyScript Knobs. But, that also didn't work.