Skip to content

Instantly share code, notes, and snippets.

@MitchellKehn
Last active March 31, 2020 04:13
Show Gist options
  • Save MitchellKehn/a0ea050552d524dbfaaf3cf02f22556b to your computer and use it in GitHub Desktop.
Save MitchellKehn/a0ea050552d524dbfaaf3cf02f22556b to your computer and use it in GitHub Desktop.
Copy the chosen transform attributes from the selected tracker node onto the transform controls of the selected elements in roto tree
"""
Copy the chosen transform attributes from the selected tracker node
onto the transform controls of the selected elements in roto tree
"""
import nukescripts
import nuke
from PySide2 import QtWidgets, QtCore, QtGui
class OptionsDialog(QtWidgets.QDialog):
def __init__(self):
super(OptionsDialog, self).__init__()
self.__setupUI()
self.__setupCallbacks()
def __setupUI(self):
self.setWindowTitle("Select transformations to copy")
mainLayout = QtWidgets.QVBoxLayout()
self.setLayout(mainLayout)
checkBoxLayout = QtWidgets.QHBoxLayout()
mainLayout.addLayout(checkBoxLayout)
self.translateCheckbox = QtWidgets.QCheckBox("translate")
self.translateCheckbox.setChecked(True)
checkBoxLayout.addWidget(self.translateCheckbox)
self.rotateCheckbox = QtWidgets.QCheckBox("rotate")
self.rotateCheckbox.setChecked(True)
checkBoxLayout.addWidget(self.rotateCheckbox)
self.scaleCheckbox = QtWidgets.QCheckBox("scale")
self.scaleCheckbox.setChecked(True)
checkBoxLayout.addWidget(self.scaleCheckbox)
self.buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
mainLayout.addWidget(self.buttonBox)
def __setupCallbacks(self):
self.buttonBox.rejected.connect(self.reject)
self.buttonBox.accepted.connect(self.accept)
def getTransformOptions(self):
return {
"translate": self.translateCheckbox.isChecked(),
"rotate": self.rotateCheckbox.isChecked(),
"scale": self.scaleCheckbox.isChecked(),
}
def copyKeys(srcKnob, dstKnob):
"""
Copy the keyframes from one knob to another.
Currently super basic and probably should have a bunch of extra
error handling and stuff when only certain channels are animated...
for now assumes that all channels in srcKnob are animated.
"""
if not type(srcKnob) == type(dstKnob): raise TypeError("knobs are of different type")
dstKnob.setAnimated()
dstAnims = dstKnob.animations()
srcAnims = srcKnob.animations()
for srcAnim, dstAnim in zip(srcAnims, dstAnims):
dstAnim.clear()
dstAnim.addKey(srcAnim.keys())
# manually set a key, otherwise some knobs forget it the whole animation
dstAnim.setKey(dstAnim.keys()[0].x, dstAnim.keys()[0].y)
def linkTrackerToRoto():
selRotos = nuke.selectedNodes("Roto")
selTrackers = nuke.selectedNodes("Tracker4")
if not (len(selRotos)==1 and len(selTrackers)==1):
nuke.message("please select 1 roto and 1 tracker node")
return
roto = selRotos[0]
tracker = selTrackers[0]
d = OptionsDialog()
result = d.exec_()
if not result == QtWidgets.QDialog.Accepted: return
options = d.getTransformOptions()
if options["translate"]:
copyKeys(tracker["translate"], roto["translate"])
if options["rotate"]:
copyKeys(tracker["rotate"], roto["rotate"])
if options["scale"]:
copyKeys(tracker["scale"], roto["scale"])
if any(options.values()):
copyKeys(tracker["center"], roto["center"])
if __name__ == "__main__":
linkTrackerToRoto()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment