Untitled
unknown
plain_text
2 years ago
5.8 kB
2
Indexable
Never
''' ScissorTool v1.0 by Jorrit Schulte Add this to menu.py: import ScissorTool ''' try: from PySide.QtGui import * from PySide.QtCore import * except ImportError: from PySide2.QtWidgets import * from PySide2.QtCore import * from PySide2.QtGui import * import nuke, threading, platform, time from pyautogui import click shortcut = 'z' #switch that keeps the ui from reopening canOpen = True class Point: def __init__(self,x,y): self.x = x self.y = y def ccw(A,B,C): return (C.y-A.y)*(B.x-A.x) > (B.y-A.y)*(C.x-A.x) def intersect(A,B,C,D): return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D) def DAGMousePos(): click() for node in nuke.selectedNodes(): node.setSelected(False) offset = nuke.toNode('preferences')['dot_node_scale'].value()*6 dot = nuke.createNode("Dot", inpanel=False) coord = Point(dot.xpos()+offset, dot.ypos()+offset) nuke.delete(dot) return coord class Panel(QWidget): finished = Signal() def __init__(self): super(Panel, self).__init__() #find active screen screen = QApplication.desktop().screenNumber(QApplication.desktop().cursor().pos()) screenSize = QDesktopWidget().screenGeometry(screen) self.screenPos = QDesktopWidget().screenGeometry(screen).topLeft() #set window size self.resize(screenSize.width(),screenSize.height()) self.move(self.screenPos.x(), self.screenPos.y()) #make window transparent self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setAttribute(Qt.WA_NoSystemBackground) self.setAttribute(Qt.WA_TranslucentBackground) if platform.system() not in ['Darwin','Windows'] and nuke.NUKE_VERSION_MAJOR < 11: self.setAttribute(Qt.WA_PaintOnScreen) #initialise cursor position self.start = QCursor().pos() - self.screenPos self.mouse_position = self.start #set timer for cursor polling self.timer = QTimer(self) self.timer.timeout.connect(self.pollCursor) self.timer.start() #install focus deactivation self.installEventFilter(self) #find initial DAG position, then open UI self.finished.connect(self.show) thread = threading.Thread(target=self.run) thread.daemon = True thread.start() def run(self): global parent #sleep a tiny amount to let the group context kick in time.sleep(0.001) with parent: self.a = DAGMousePos() self.finished.emit() #keeps the ui from reopening def keyPressEvent(self,event): if event.isAutoRepeat(): return def keyReleaseEvent(self,event): if event.isAutoRepeat(): return if event.text() == shortcut: self.closeWidget() return #focus deactivation def eventFilter(self, object, event): if event.type() in [QEvent.WindowDeactivate, QEvent.FocusOut] and not canOpen: self.closeWidget() return True return False #polling of the cursor def pollCursor(self): self.mouse_position = QCursor().pos() - self.screenPos self.update() #create the line def paintEvent(self, QPaintEvent): super(Panel, self).paintEvent(QPaintEvent) painter = QPainter(self) pen = QPen(QColor(200,0,0)) pen.setWidth(2) pen.setStyle(Qt.DotLine) painter.setPen(pen) painter.setRenderHint(QPainter.Antialiasing) line = QLine(self.start, self.mouse_position) painter.drawLine(line) def cut(self): global parent with parent: undo = nuke.Undo() undo.begin("Scissor Tool") #define starting point and get end point scissor line a = self.a b = DAGMousePos() #find all connections for nodeA in nuke.allNodes(): connections = nodeA.dependencies(nuke.INPUTS) if len(connections) > 0: c = Point(nodeA.xpos()+(nodeA.screenWidth()/2),nodeA.ypos()+(nodeA.screenHeight()/2)) for nodeB in connections: d = Point(nodeB.xpos()+(nodeB.screenWidth()/2),nodeB.ypos()+(nodeB.screenHeight()/2)) #check for intersection with scissor line if intersect(a,b,c,d): for i in range(nodeA.inputs()): #disconnect if current input is connected to other node if nodeA.input(i) is nodeB: nodeA.setInput(i, None) undo.end() def closeWidget(self): global canOpen canOpen = True #stop the polling timer self.timer.stop() #close widget self.close() #run intersect code thread = threading.Thread(target=self.cut) thread.daemon = True thread.start() return def run(): global canOpen if canOpen: #create dot to find group context contextDot = nuke.createNode("Dot", inpanel=False) fnn = contextDot.fullName().split('.') groupName = 'root.' for i in range(len(fnn)-1): groupName += fnn[i] + '.' #get parent global parent if groupName != 'root.': parent = nuke.toNode(groupName[:-1]) else: parent = nuke.root() #initialize panel run.panel = Panel() #turns off canOpen so the ui doesnt reopen canOpen = False #delete dot again nuke.delete(contextDot) menubar = nuke.menu('Nuke') menubar.addCommand('@;Scissor tool', run , shortcut)