Untitled
unknown
plain_text
2 years ago
8.9 kB
1
Indexable
Never
import nuke import math def ConcatTransform_getMatrix(node, frame=nuke.frame()): if node.Class() == 'Transform': t = node['translate'].valueAt(frame) r = node['rotate'].valueAt(frame) sc = node['scale'].valueAt(frame) if type(sc) is float: sc = [sc,sc] sx = node['skewX'].valueAt(frame) sy = node['skewY'].valueAt(frame) p = node['center'].valueAt(frame) #pivot pivot = nuke.math.Matrix4() pivot.makeIdentity() pivot.translate(-p[0],-p[1],0) pivot.transpose() inv = pivot.inverse() #transform matrix = nuke.math.Matrix4() matrix.makeIdentity() matrix.translate(t[0],t[1],0) matrix.rotateZ((math.pi/180)*r) if node['skew_order'].value() == 'XY': matrix.skewXY(sx,sy) else: matrix.skewXY(0,sy) matrix.skewXY(sx,0) matrix.scale(sc[0],sc[1],1) matrix.transpose() matrix = pivot*matrix*inv if node['invert_matrix'].value(): matrix = matrix.inverse() return matrix elif node.Class() == 'CornerPin2D': to1x, to1y = node['to1'].valueAt(frame) to2x, to2y = node['to2'].valueAt(frame) to3x, to3y = node['to3'].valueAt(frame) to4x, to4y = node['to4'].valueAt(frame) from1x, from1y = node['from1'].valueAt(frame) from2x, from2y = node['from2'].valueAt(frame) from3x, from3y = node['from3'].valueAt(frame) from4x, from4y = node['from4'].valueAt(frame) To = nuke.math.Matrix4() From = nuke.math.Matrix4() To.mapUnitSquareToQuad(to1x,to1y,to2x,to2y,to3x,to3y,to4x,to4y) From.mapUnitSquareToQuad(from1x,from1y,from2x,from2y,from3x,from3y,from4x,from4y) matrix = To*From.inverse() matrix.transpose() extraMatrix = nuke.math.Matrix4() for index, value in enumerate(node['transform_matrix'].getValueAt(frame)): extraMatrix[index] = value matrix = matrix*extraMatrix if node['invert'].value(): matrix = matrix.inverse() return matrix def ConcatTransform_concatMatrix(node, frame=nuke.frame()): #collect transforms look = True un = node.input(1) tn = [] while look: if un is None: look = False elif un.Class() in ['Dot', 'NoOp']: un = un.input(0) elif un.Class() == 'Switch': un = un.input(int(un['which'].valueAt(frame))) elif un.Class() in ['Transform', 'CornerPin2D']: if not un['disable'].valueAt(frame): tn.append(un) un = un.input(0) else: look = False tn = list(reversed(tn)) #return identity matrix if no nodes found if len(tn) == 0: matrix = nuke.math.Matrix4() matrix.makeIdentity() return matrix #get concatinated matrix matrix = ConcatTransform_getMatrix(tn[0], frame) for i in tn[1:]: matrix = matrix * ConcatTransform_getMatrix(i, frame) #compensate for ref frame if node['use'].value(): rframe = int(node['ref'].value()) refMatrix = ConcatTransform_getMatrix(tn[0], rframe) for i in tn[1:]: refMatrix = refMatrix * ConcatTransform_getMatrix(i, rframe) refMatrix = refMatrix.inverse() matrix = matrix * refMatrix #invert if wanted if node['invert'].value(): matrix = matrix.inverse() return matrix def ConcatTransform_detectCP(node): look = True un = node.input(1) cornerpin = False while look: if un is None: look = False elif un.Class() in ['Dot', 'NoOp', 'Transform']: un = un.input(0) elif un.Class() == 'Switch': un = un.input(int(un['which'].valueAt(frame))) elif un.Class() == 'CornerPin2D': if un['disable'].value(): un = un.input(0) else: cornerpin = True look = False else: look = False return cornerpin def run(): node = nuke.thisNode() width = node.width() height = node.height() #determine whether to create a Transform or CornerPin op = node['outputNode'].value() if op == 'CornerPin': cornerpin = True elif op == 'Transform': if ConcatTransform_detectCP(node) and not nuke.ask('A CornerPin is detected upstream, a transform might not be able to faithfully recreate the resulting matrix. continue?'): return cornerpin = False elif op == 'Detect': cornerpin = ConcatTransform_detectCP(node) #set range if node['noAnim'].value(): frames = [nuke.frame()] else: #multiple frames start = int(nuke.root()['first_frame'].value()) end = int(nuke.root()['last_frame'].value()) retu = nuke.getFramesAndViews('bake range', str(start) + '-' + str(end)) try: r = [int(i) for i in retu[0].split('-')] frames = range(r[0],r[1]) except: return #find group name if node is in group fnn = node.fullName().split('.') groupName = 'root.' for i in range(len(fnn)-1): groupName += fnn[i] + '.' #get parent if groupName != 'root.': parent = nuke.toNode(groupName[:-1]) else: parent = nuke.root() with parent: if cornerpin: #create CornerPin cp = nuke.nodes.CornerPin2D() cp['xpos'].setValue(node['xpos'].value()+100) cp['ypos'].setValue(node['ypos'].value()+50) cp['from2'].setValue([width,0]) cp['from3'].setValue([width,height]) cp['from4'].setValue([0,height]) cp.showControlPanel() if not node['noAnim'].value(): cp['to1'].setAnimated() cp['to2'].setAnimated() cp['to3'].setAnimated() cp['to4'].setAnimated() #convert matrix to cornerpin values for frame in frames: matrix = ConcatTransform_concatMatrix(node, frame) matrix.transpose() v1 = nuke.math.Vector4(0, 0, 0, 1) v1 = matrix.transform(v1) v1 /= v1.w v2 = nuke.math.Vector4(width, 0, 0, 1) v2 = matrix.transform(v2) v2 /= v2.w v3 = nuke.math.Vector4(width, height, 0, 1) v3 = matrix.transform(v3) v3 /= v3.w v4 = nuke.math.Vector4(0, height, 0, 1) v4 = matrix.transform(v4) v4 /= v4.w for i in range(2): cp['to1'].setValueAt(v1[i], frame, i) cp['to2'].setValueAt(v2[i], frame, i) cp['to3'].setValueAt(v3[i], frame, i) cp['to4'].setValueAt(v4[i], frame, i) else: #create Transform node t = nuke.nodes.Transform() t['xpos'].setValue(node['xpos'].value()+100) t['ypos'].setValue(node['ypos'].value()+50) t['center'].setValue([width/2,height/2]) t.showControlPanel() if not node['noAnim'].value(): t['translate'].setAnimated() t['rotate'].setAnimated() t['scale'].setAnimated() t['skewX'].setAnimated() #convert matrix to transform values for frame in frames: matrix = ConcatTransform_concatMatrix(node, frame) matrix.transpose() vector = nuke.math.Vector3(width/2, height/2, 0) vector_trans = matrix.transform(vector) delta = (matrix[0] * matrix[5]) - (matrix[4] * matrix[1]) r = pow(matrix[0], 2) + pow(matrix[1], 2) translate_x = vector_trans[0] - width/2 translate_y = vector_trans[1] - height/2 rotation = math.degrees(math.atan2(matrix[1], matrix[0])) scale_x = math.sqrt(r) scale_y = delta / scale_x skew_x = (matrix[0] * matrix[4] + matrix[1] * matrix[5]) / delta t['translate'].setValueAt(translate_x, frame, 0) t['translate'].setValueAt(translate_y, frame, 1) t['rotate'].setValueAt(rotation, frame) t['scale'].setValueAt(scale_x, frame, 0) t['scale'].setValueAt(scale_y, frame, 1) t['skewX'].setValueAt(skew_x, frame)