def comeon(self): # SHOW ERROR IF NO BACKDROPS FOUND if any(n.Class() == 'BackdropNode' for n in nuke.allNodes()): pass else: nuke.message('No Backdrops Found!') raise KeyError, 'No Backdrops Found!' # CHECKING IF ANY OF THE SELECTED NODES ARE BACKDROPS for b in nuke.selectedNodes(): if b.Class() == 'BackdropNode': self.nodes = True # RESETS LIST BY DELETING THE CURRENT ONE del self.elements[:] for a in self.srcNodes[self.nodesChoice.value()]: if a.Class() == 'BackdropNode': # IF BACKDROP IS BLANK THEN TEMPORARILY CHANGE IT TO ITS NAME if a.knob('label').value() == '': a.knob('label').setValue(a.knob('name').value()) # ALLOCATING BACKDROP VALUES TO DICTIONARIES self.key[a.knob('label').value()] = a self.key[a] = a.knob('tile_color').value() self.fontset[a] = a.knob('note_font').value() self.fontsize[a] = int(a.knob('note_font_size').value()) self.fontcol[a] = a.knob('note_font_color').value() g = a.knob('label').value() self.elements.append(g) # CHANGE TEMPORARILY BACKDROPS BACK TO BLANK for b in self.srcNodes[self.nodesChoice.value()]: if b.knob('label').value() == b.knob('name').value(): b.knob('label').setValue('') return self.elements
def sb_revealInFileBrowser(): n = nuke.selectedNodes("Read") + nuke.selectedNodes("Write") if len(n) == 0: nuke.message("Select at least one Read or Write node.") return if len(n) > 3: makeSure = nuke.ask("Are you sure you want to open {0} file browser windows?".format(len(n))) if not makeSure: return for i in n: try: getPath = i["file"].evaluate().split("/")[:-1] folderPath = "/".join(getPath) if platform.system() == "Windows": subprocess.Popen('explorer "{0}"'.format(folderPath.replace("/", "\\"))) elif platform.system() == "Darwin": subprocess.Popen(["open", folderPath]) elif platform.system() == "Linux": subprocess.Popen(["xdg-open", folderPath]) except: continue
def duplicateNode(self): """ duplicates an exact copy of the selected node, including all animations """ try: self.__duplicate(nuke.selectedNode()) except: nuke.message("Error - no node selected")
def load_src(): import pipe asset_obj = pipe.Projects().GetAssetByInfo(nuke.root().name()) if not asset_obj: return shot_obj = asset_obj.GetShot() if not shot_obj: raise Exception('Shot not found') src_path = shot_obj.GetSrcPath() sequences = condensing_is(src_path,'src') if not sequences: nuke.message("There aren't files in folder SRC") filenameSearch = "Load" enumerationPulldownp = "None " + ' '.join(sequences.keys()) p = nuke.Panel("Presets selection") p.addEnumerationPulldown("SRC to load:", enumerationPulldownp) p.addButton("Cancel") p.addButton("Load") result = p.show() enumVal = p.value("SRC to load:") if enumVal == 'None': return #nuke.message(sequences[enumVal]) n = nuke.toNode(enumVal) if not n: n = nuke.createNode('Read', inpanel=False) n.setName(enumVal) n.knob('file').fromUserText(sequences[enumVal])
def thumb_snap(self): self.check_for_tmp() #lets make sure were snapping for the current shot shot = self.shotcombo.currentText() if os.getenv('SHOT') == shot: viewer = nuke.activeViewer() actInput = nuke.ViewerWindow.activeInput(viewer) viewNode = nuke.activeViewer().node() selInput = nuke.Node.input(viewNode, actInput) reformatNode = nuke.nodes.Reformat( type = "to format", format = "240 135 eight_scaled", resize = 'fill') reformatNode.setInput(0, selInput) self.shot_thumb = os.path.join(jeeves_core.jobsRoot, self.job, 'vfx', 'nuke', self.shot, 'plates', '.tmp', '%s.jpg' % self.shot).replace('\\', '/') writeNode = nuke.nodes.Write( file = self.shot_thumb, name = 'tmpWrite2' , file_type = 'jpg') writeNode.setInput(0,reformatNode) curFrame = int(nuke.knob("frame")) nuke.execute(writeNode.name(), curFrame, curFrame) nuke.delete(writeNode) nuke.delete(reformatNode) self.update_thumb() else: #print 'not snapping for current shot' nuke.message('not snapping for current shot')
def trackedRoto(node): """Given a node with appropriate transform knobs (see nodeHasTransformKnobs), create a new Roto node with it's Root's tranform knobs expression-linked to the source node. """ if not nodeHasTransformKnobs(node): nuke.message("Sorry boss, can't link a bezier to this one.") # Build knob list knob_list = ['translate', 'rotate', 'scale', 'skew', 'center'] node.setSelected(False) # Build Roto node r = nuke.createNode('Roto') # This doesn't work for a Roto node, so we have to get all nasty with the curves knob. #for knob in knob_list: # r.knob(knob).setExpression(node.name()+'.'+knob) # Create new layer and set it's transforms to be expression-driven by the source node. curves = r.knob('curves') tracked_layer = nuke.rotopaint.Layer(curves) tracked_layer.name = 'tracked_to_' + node.name() print tracked_layer, dir(tracked_layer) curves.rootLayer.append(tracked_layer)
def makeBackup(): ''' make backup of script ''' #get script name and make folder if not exist script = nuke.root().name() scriptName = (nuke.root().name().split("/")[-1]).replace(".nk","") operation=blackboxHelper.getBackupSettings("@operation", backupSettings) backupPath=blackboxHelper.getBackupSettings("@backupPath", backupSettings) numberOfBackups=int(blackboxHelper.getBackupSettings("@numberOfBackups", backupSettings)) if backupMinute == True: t = time.strftime("%y%m%d-%H%M") else: t = time.strftime("%y%m%d-%H%M%S") # global dir if operation=="0.0": if not os.path.isdir(backupPath+"/"+scriptName): os.makedirs(backupPath+"/"+scriptName) try: nuke.removeOnScriptSave(makeBackup) nuke.scriptSave(backupPath+"/"+scriptName+"/bckp_"+t+"_"+scriptName+".nk") nuke.addOnScriptSave(makeBackup) except Exception, e: nuke.message("couldn't write a backup file") deleteOlderBackupVersions(backupPath+"/"+scriptName)
def knobChanged(self, knob): """Handles knob callbacks.""" if knob is self.okButton: # Run presubmit checks to make sure the job is ready to be launched with the currently selected parameters. we do # this here so we can display errors to the user before the dialog closes and destroys all of their settings. we # cannot do the full job submission here though, because trying to use nuke.Undo functionality while a modal # dialog is open crashes Nuke. try: self.submit_checks() # Raised exceptions will automatically cause Nuke to abort and leave the dialog open. we just capture that and # show a message to the user so they know what went wrong. the full exception will be printed to the Script # Editor for further debugging. except Exception as e: nuke.message(str(e)) raise elif knob is self.loginButton: # Run the auth flow, and display the user's email address, adding a little whitespace padding for visual clarity. self.userLabel.setValue(' %s' % self.zync_conn.login_with_google()) elif knob is self.logoutButton: self.zync_conn.logout() self.userLabel.setValue('') elif knob is self.upload_only: checked = self.upload_only.value() for rk in self.render_knobs: rk.setEnabled(not checked) for k in self.writeNodes: k.setEnabled(not checked) elif knob is self.num_slots or knob is self.instance_type: self.update_pricing_label()
def flopViewer(): """input process to flop the viewer""" allV = nuke.allNodes('Viewer') pV = allV[0] List = nuke.selectedNodes() nuke.selectAll() nuke.invertSelection() try: n = nuke.toNode('VIEWER_INPUT') if n.Class() == 'Mirror': n['Vertical'].setValue(not n['Vertical'].value()) for i in allV: i['input_process'].setValue(not n['Vertical'].value() + n['Horizontal'].value() == 0) if n['Vertical'].value() + n['Horizontal'].value() == 0: nuke.delete(n) nuke.selectAll() nuke.invertSelection() else: nuke.message("Another Viewer Input already exists.\nAborting to avoid conflict") except: n = nuke.Node('Mirror',inpanel=False) n['xpos'].setValue(pV.xpos()+150) n['ypos'].setValue(pV.ypos()) n['name'].setValue('VIEWER_INPUT') n['hide_input'].setValue(1) n['Vertical'].setValue(not n['Vertical'].value()) nuke.selectAll() nuke.invertSelection() for i in List: i['selected'].setValue(True) for i in List: i['selected'].setValue(True)
def sb_onOff(): sn = nuke.selectedNodes() if len(sn) == 0: nuke.message("Select a node.") return frame = int(nuke.frame()) p = nuke.Panel( "sb_onoff" ) p.addSingleLineInput( "first frame:", "") p.addSingleLineInput( "last frame:", "") result = p.show() if result: ff = int(p.value("first frame:")) lf = int(p.value("last frame:")) for i in nuke.selectedNodes(): m = nuke.createNode("Multiply", inpanel = False) m["channels"].setValue("all") val = m["value"] val.setAnimated() val.setValueAt(1, ff) val.setValueAt(1, lf) val.setValueAt(0, ff-1) val.setValueAt(0, lf+1) m.setInput(0, i) m["xpos"].setValue(i["xpos"].value()) m["ypos"].setValue(i["ypos"].value() + 75) m["selected"].setValue(False) i["selected"].setValue(False)
def browseDir(action): if (nuke.root().name() == 'Root') and (action != 'Path'): nuke.message('You need to save the Nuke script first!') else: # Get full path to script scriptPath = nuke.callbacks.filenameFilter( nuke.root().name() ) # Divide up the paths scriptPathSplitted = str.split( scriptPath, '/' ) # Reset openMe = '' if action == 'scripts': for i in range(0, (len(scriptPathSplitted)-1) ): openMe = openMe + scriptPathSplitted[i] + '/' elif action == 'sequence': for i in range(0, (len(scriptPathSplitted)-4) ): openMe = openMe + scriptPathSplitted[i] + '/' elif action == 'shot': for i in range(0, (len(scriptPathSplitted)-3) ): openMe = openMe + scriptPathSplitted[i] + '/' launch(openMe)
def gizmoLoadSetter(): allGizmosFolder = [] if os.path.isdir(gizmosPath): gizmoDirsArr = os.listdir(gizmosPath) for i in gizmoDirsArr: if os.path.isdir(gizmosPath+"/"+i): allGizmosFolder.append(i) p = createPanel(allGizmosFolder) if p.show(): loadArr=[] #update loadinglist for group in allGizmosFolder: groupValue=(p.value(group)) if groupValue is True: loadArr.append(group) outp = open(gizmoLoaderSetting,'w') loadOutput ="" for i in loadArr: loadOutput=loadOutput+i+"\n" l = outp.write(loadOutput) outp.close loadGizmos(loadArr) else: nuke.message("gizmos folder not found")
def createReadFromWrite(nodes=[]): ''' function to create a read node from a selected write node ''' # if no nodes are defined look for selected nodes if not nodes: nodes = nuke.selectedNodes() # if nodes is still empty, nothing is selected if nodes == (): nuke.message('ERROR: No node(s) selected.') return #work around to select single node as an object node = nodes[0] _class = node.Class() if _class == "Write": file = node.knob('file').getValue() proxy = node.knob('proxy').getValue() first = nuke.toNode('root').knob('first_frame').getValue() last = nuke.toNode('root').knob('last_frame').getValue() xpos = node.knob('xpos').getValue() ypos = int(node.knob('ypos').getValue()) + 40 knobs = [] fields = ('file','proxy','first','last','xpos','ypos') for entry in fields: if eval(entry) != '': knobs.append(entry) knobs.append(str(eval(entry))) nuke.createNode('Read', string.join(knobs)) return
def checkFor( searchString ): searchString = searchString.replace("_", " " ).lower() nodes = [] for node in nuke.allNodes(): knobs = node.allKnobs() for knob in knobs: try: if searchString in getExp( knob ): nodes.append( node ) except: try: if searchString in knob.value(): nodes.append( node ) except: pass if searchString in node.Class().replace("_", " " ).lower() and node not in nodes: nodes.append( node ) if searchString in node.name().replace("_", " " ).lower() and node not in nodes: nodes.append( node ) if len(nodes): if (len(nodes) -1): manyNodes = "There are " + str(len(nodes)) + " node" + "s that have \"" + searchString + "\" in it. They are:" else: manyNodes = "There is " + str(len(nodes)) + " node" + " that has \"" + searchString + "\" in it. It is:" for i in nodes: i['selected'].setValue(True) manyNodes += ( "\n" + i.name() ) nuke.message(manyNodes) print "done"
def submitToDeadline (jobInfoFile, pluginInfoFile): submitCmd = ('%s %s %s' % (deadlineCommand, jobInfoFile, pluginInfoFile)) stdout = os.popen(submitCmd) stdoutParse = stdout.read() jobID = stdoutParse.split('=')[len(stdoutParse.split('='))-1] jobID = jobID.strip() nuke.message('Job Submitted : %s' % (jobID))
def callPanel(): plate = nuke.selectedNode() if plate.Class() == "Read": return setProjectFrameRange().showPanel() else: nuke.tprint("Selected node must be a Read node.") nuke.message("Selected node must be a Read node.")
def PasteToSelected(): # put selection in variable and find out if nodes are valid original_selection = nuke.selectedNodes() for node in original_selection: if node.Class() == "Viewer" or node.name() == "VIEWER_INPUT": node.knob("selected").setValue(False) valid_selection = nuke.selectedNodes() for a in nuke.allNodes(): a.knob("selected").setValue(False) # create dict for new nodes so they can be selected later new_nodes = [] # go through selection and paste from clipboard to each for b in valid_selection: b.knob("selected").setValue(True) nuke.nodePaste(nukescripts.cut_paste_file()) new_nodes += nuke.selectedNodes() for pasted in nuke.selectedNodes(): pasted.knob("selected").setValue(False) # re-select original nodes for c in new_nodes: c.knob("selected").setValue(True) if len(valid_selection) is not len(original_selection): nuke.message("Some Viewer or VIEWER_LUT nodes were ignored. Rad.")
def autoBackup(): root = nuke.toNode("root") srcPath = root.name() (dirPath, fileName) = os.path.split(srcPath) (Scene, Shot, Tail) = fileName.split("_") (Version, Extention) = Tail.split(".") #upVersion = int(Version[-2:]) + 1 #upVersion = "0" + upVersion enumerationPulldown = "Project1 Project2 Project3" p = nuke.Panel("Select Project") p.addEnumerationPulldown("Select NodeType:", enumerationPulldown) result = p.show() Project = p.value("Select NodeType:") backupSystem = "\\\skycomp\Projects_Backup" dstDir = backupSystem + "\\" + Project + "\\" + Scene if os.path.isdir(dstDir): print "already exists" else: print "not exists" os.mkdir(dstDir) dstDir = backupSystem + "\\" + Project + "\\" + Scene + "\\" + Shot if os.path.isdir(dstDir): print "already exists" else: print "not exists" os.mkdir(dstDir) dstPath = backupSystem + "\\" + Project + "\\" + Scene + "\\" + Shot + "\\" + fileName print dstPath shutil.copyfile(srcPath, dstPath) nuke.message("File copied to " + dstPath)
def createWriteFromRead(nodes=[]): ''' function to create a write node from a selected read node ''' # if no nodes are defined look for selected nodes if not nodes: nodes = nuke.selectedNodes() # if nodes is still empty, nothing is selected if not nodes: nuke.message('ERROR: No node(s) selected.') return for node in nodes: _class = node.Class() if _class == "Read": file = node.knob('file').getValue() proxy = node.knob('proxy').getValue() first = nuke.toNode('root').knob('first_frame').getValue() last = nuke.toNode('root').knob('last_frame').getValue() xpos = node.knob('xpos').getValue() ypos = int(node.knob('ypos').getValue()) + 40 knobs = [] fields = ('file','proxy','first','last','xpos','ypos') for entry in fields: if eval(entry) != '': knobs.append(entry) #knobs.append(str(eval(entry))) nuke.createNode('Write', string.join(knobs)) return
def nk_open_dependents(): """ Open all dependents """ def gen(x): while True: x+=1 yield "_%i" % x suffix = gen(0) p = nuke.Panel('Open dependents') if not len(nuke._selectedNodes()): nuke.message("No nodes selected.") else: root = nuke._selectedNodes()[0] crawl = [root] node_options = {} while len(crawl)>0: this = crawl.pop() name = this.name() if node_options.has_key(name): name+=suffix.next() node_options[name] = this [crawl.append(n) for n in this.dependencies() if n.Class() not in ["Dot"]] node_options_keys = sorted(node_options.keys()) p.addEnumerationPulldown('dependencies', " ".join(node_options_keys)) p.show() target = p.value('dependencies') if target: node_options[target].showControlPanel()
def render( self ): frame_range = self.panel.value("Frame Range") thread_count = self.panel.value("Num Threads") chunk_size = self.panel.value("Frames per Chunk") force_fullsize = self.panel.value("Force Fullsize") quiet_mode = self.panel.value("Quiet Mode") render_name = self.panel.value("Render Name") if chunk_size == "None": chunk_size = 0 username = getpass.getuser() timestamp = int( time.time() ) if render_name is None: render_name = "Nuke Render for %s" % username filename = "/tmp/nuke-%s-%s-%s.nk" % ( frame_range, username, timestamp ) try: nuke.scriptSave( filename ) print filename except: nuke.message("ERR-001 Unable to save spool file") nuke_args = { "type":"Nuke", "threads":thread_count, "fullsize":force_fullsize, "quiet":quiet_mode, "file":filename, "nodes":self.writeNodes} render_args = { "range":frame_range, "chunksize":chunk_size, "timestamp":timestamp, "name":render_name, "user":username,} print render_args print nuke_args rr = tractor.Render( render_args, nuke_args ) rr.build() rr.spool()
def runPane(): paneExistsCheck = nuke.getPaneFor('org.vfxwiki.nuketoolkit') if not paneExistsCheck: pane = nuke.getPaneFor('Properties.1') nukescripts.registerWidgetAsPanel('toolSetWidget', 'openNuke', 'org.vfxwiki.nuketoolkit', True).addToPane(pane) else: nuke.message("errr. unable to load pane, as it already exists. \nClose the 'WebTools' pane, and try again.")
def copyKeys(verbose=False): tmpDir = os.environ['NUKE_TEMP_DIR']+'/' if verbose: print ('tempDir is '+tmpDir) numViews=len(nuke.views()) keysList=[] for node in nuke.allNodes(): nodeAnimated=isNodeAnimated(node) if nodeAnimated : for knob in node.knobs().values(): if knob.isAnimated(): aSize = knob.arraySize() for index in range(aSize): for vues in range(1,numViews+1): anim = knob.animation(index,vues) try: numKeys=anim.size() except: continue if numKeys: #step through the keys - check if they are selected then paste the values from timebar onwards for i in range(numKeys): keySelected= (anim.keys()[i].selected) if keySelected: keyVals= (anim.keys()[i].x, anim.keys()[i].y) if verbose: print ('keySelected: '+str(keySelected)+' keyvalues: '+str(keyVals)) keysList.append((keyVals[0],keyVals[1])) i+=1 if verbose: nuke.message(str(keysList)) return (keysList)
def smartSaver(): r=nuke.root()['name'].value() #root if r!="": rArray = r.split("/"); rootLast = rArray[len(rArray)-1] rArray.pop() directoryPath = '/'.join(rArray) nameArray = rootLast.split(".") projectName=nameArray[0] #delete lastTime from project name projectNameZeroDateArr = projectName.split("@") projectNameZeroDate = projectNameZeroDateArr[0] t = getTime() safeTo = directoryPath+"/"+projectNameZeroDate+"@"+t+".nk" nuke.scriptSaveAs(safeTo) #add current script to SmartRecentScripts saveInSmartRecentScripts(safeTo) else: nuke.message("You haven't saved your nuke project. Please make sure to save your project first in order to proceed.")
def bookmarkthis( desc=True, ask=True ): '''Bookmarks a node for quick navigation''' try: sn = nuke.selectedNodes()[-1] except: nuke.message('Please select a node') sn = None if sn is not None: if sn['icon'].value() != 'bookmark.png' and desc == True: l=sn['label'].value() panel = nuke.Panel ('Bookmark This',300) panel.addSingleLineInput('add description',l) result=panel.show() d = panel.value('add description') if result: sn['icon'].setValue('bookmark.png') sn['label'].setValue(d) else: if ask: clear=nuke.ask('Clear Bookmark and Label?') if clear: sn['icon'].setValue('') sn['label'].setValue('') else: if desc: sn['icon'].setValue('') sn['label'].setValue('') else: sn['icon'].setValue('')
def listbookmarks(): bm=[] zoomBy=1 #find bookmark nodes for n in nuke.allNodes(): n['selected'].setValue( False ) if n['icon'].value() == 'bookmark.png': n['selected'].setValue( True ) #select nodes for clarity bmLabel=nuke.selectedNode()['label'].value() if bmLabel: bm_name='"'+bmLabel+'"' # '"'<-lets it list correctly else: bm_name='"'+n.name()+'"' # '"'<-allows it to be sorted correctly with above bm.append(bm_name) if 0==len(bm): nuke.message('no bookmarks found') else: bookmarkList=str(sorted(bm)) #clean up list name pattern = re.compile('[\[\]\']') bookmarkList = pattern.sub('', bookmarkList) pattern = re.compile('[\,]') bookmarkList = pattern.sub(' ', bookmarkList) #let user choose bookmark panel = nuke.Panel ('BookMarks',200) panel.addEnumerationPulldown('go to',bookmarkList) panel.addSingleLineInput('zoom',zoomBy) panel.addBooleanCheckBox('also open node', False) panel.addButton("Cancel") panel.addButton("Zoom to") panel.addButton("Open") result=panel.show() if result: goto= panel.value('go to') zoomf= panel.value('zoom') alwaysOpen= panel.value('also open node') #select only relevent node for n in nuke.allNodes(): if goto == n.name() or goto == n['label'].value(): n['selected'].setValue( True ) else: n['selected'].setValue( False ) #set nuke to highlight chosen node, get xy pos and zoom into area and open if selected. if result ==1: nuke.zoom(float(zoomf),(nuke.selectedNode().xpos(),nuke.selectedNode().ypos())) if alwaysOpen: nuke.show(nuke.selectedNode()) elif result ==2: nuke.show(nuke.selectedNode()) else: pass
def openNukeFile(self, filename): filename = filename.replace('\\', '/') filebase, ext = os.path.splitext(filename) if ext == '.nk': nuke.scriptOpen(filename) else: nuke.message('Invalid nuke script. Please open a .nk script only')
def loadAOV(): node_info = getNodeList() for rnd in node_info: aovDict = getAOV(rnd) if len(aovDict) > 0: aovGroup = nuke.nodes.Group(name = 'AOV', label = rnd['display_name']) # put scope to AOVgroup level nuke.Group.begin(aovGroup) n_input = nuke.nodes.Input() n_output = nuke.nodes.Output() lastShuffle = n_input xpos_read = lastShuffle.xpos()-100 for aovkey, filepath in aovDict.iteritems(): lastShuffle = buildAOVGroup(aovkey, filepath, rnd['first_frame'], rnd['last_frame'], lastShuffle, xpos_read) n_output.setXYpos(n_input.xpos(), n_input.ypos()+(len(aovDict)+1)*100) n_output.setInput(0, lastShuffle) # bring back scope to root level nuke.Group.end(aovGroup) makeAOVGroup(rnd['node'], aovDict, aovGroup) else: nuke.message('No AOVs found in Folder '+rnd['fd']+' for Node '+rnd['node_name']) return
def getShotNotes(): '''Gets the current frame range from Shotgun and pushes the data to nuke. Requires that you have certain parameters set (see below for variables) THese parameters are pretty standard in Shotgun but you can customize below. ''' sg = shotgunUtils.genericUtils() scriptName = nuke.root()['name'].value() print 'foo' if scriptName == '' : nuke.message ('You need to save this first!') else: projectText = scriptName.split('/')[2] shotText = scriptName.split('/')[5] project = sg.project(projectText) shot = sg.shot(project, shotText) curNotes = sg.notesFindLatest(shot) noteDate = datetime.datetime.date(curNotes['created_at']).isoformat() noteContent = '<div>Subject : %s\nDate : %s\n%s\nContent: \n\n%s</div>' % (curNotes['subject'], noteDate, '-'*30, curNotes['content']) nodeNote = nuke.toNode('ShotgunNotes') if nodeNote == None: nodeNote = nuke.nodes.StickyNote(name='ShotgunNotes') nodeNote['label'].setValue(noteContent)
def main(): # Get the repository root try: stdout = None if os.path.exists("/Applications/Deadline/Resources/bin/deadlinecommand"): stdout = os.popen("/Applications/Deadline/Resources/bin/deadlinecommand GetRepositoryRoot") else: stdout = os.popen("deadlinecommand GetRepositoryRoot") path = stdout.read() stdout.close() if path == "" or path == None: nuke.message( "The SubmitNukeToDeadline.py script could not be found in the Deadline Repository. Please make sure that the Deadline Client has been installed on this machine, that the Deadline Client bin folder is in your PATH, and that the Deadline Client has been configured to point to a valid Repository." ) else: path += "/submission/Nuke" path = path.replace("\n", "").replace("\\", "/") # Add the path to the system path print 'Appending "' + path + '" to system path to import SubmitNukeToDeadline module' sys.path.append(path) # Import the script and call the main() function import SubmitNukeToDeadline SubmitNukeToDeadline.SubmitToDeadline(path) except IOError: nuke.message( "An error occurred while getting the repository root from Deadline. Please try again, or if this is a persistent problem, contact Deadline Support." )
def silhouetteFxsExporter(): ''' Main exporter code, UI ''' try: rotoNode = nuke.selectedNode() if rotoNode.Class() not in ('Roto', 'RotoPaint'): if nuke.GUI: nuke.message( 'Unsupported node type. Selected Node must be Roto or RotoPaint' ) return except: if nuke.GUI: nuke.message('Select a Roto or RotoPaint Node') return #=========================================================================== # Nuke UI panel setup #=========================================================================== p = nukescripts.panels.PythonPanel("FXS Shape Exporter") k = nuke.String_Knob("framerange", "FrameRange") k.setFlag(nuke.STARTLINE) k.setTooltip( "Set the framerange to bake the shapes, by default its the project start-end. Example: 10-20" ) p.addKnob(k) k.setValue("%s-%s" % (nuke.root().firstFrame(), nuke.root().lastFrame())) k = nuke.Boolean_Knob("bake", "Bake Shapes") k.setFlag(nuke.STARTLINE) k.setTooltip("Export the shapes baking keyframes and transforms") p.addKnob(k) result = p.showModalDialog() if result == 0: return # Canceled try: fRange = nuke.FrameRange(p.knobs()["framerange"].getText()) except: if nuke.GUI: nuke.message( 'Framerange format is not correct, use startframe-endframe i.e.: 0-200' ) return #=========================================================================== # end of panel #=========================================================================== start_time = time.time() rptsw_shapeList = [] global cancel cancel = False if nuke.NUKE_VERSION_MAJOR > 6: #======================================================================= # creates a copy of the node to modify and keep original safe #======================================================================= nukescripts.node_copypaste() #======================================================================= bakeshapes = p.knobs()["bake"].value() rptsw_shapeList = [] rotoNode = nuke.selectedNode() rotoCurve = rotoNode['curves'] rotoRoot = rotoCurve.rootLayer #=*=*=*=*=*=*==task=related=code======================================== task = nuke.ProgressTask('FXS Shape Exporter') task.setMessage('Starting FXS export') task.setProgress(10) #=*=*=*=*=*=*==task=related=code======================================== rptsw_shapeList = rptsw_walker(rotoRoot, rptsw_shapeList) #======================================================================= # creates additional layers to handle shape transforms #======================================================================= #=*=*=*=*=*=*==task=related=code======================================== task.setMessage('Sorting out Transforms') task.setProgress(20) #=*=*=*=*=*=*==task=related=code======================================== uniqueNames(rptsw_shapeList) if not bakeshapes: manageTransforms(fRange, rotoNode, rptsw_shapeList) #,task) #=*=*=*=*=*=*==task=related=code======================================== if cancel: return #=*=*=*=*=*=*==task=related=code======================================== rotoCurve.changed() #just for debugging purposes #======================================================================= rptsw_shapeList = [] rptsw_shapeList = rptsw_walker(rotoRoot, rptsw_shapeList) nodeFormat = rotoNode['format'].value() fxsExport = ET.Element( 'Silhouette', { 'width': str(nodeFormat.width()), 'height': str(nodeFormat.height()), 'workRangeStart': str(fRange.first()), 'workRangeEnd': str(fRange.last()), 'sessionStartFrame': str(fRange.first()) }) #======================================================================= # create the root layer first #======================================================================= item = [rotoRoot, rotoRoot] createLayers(item, fRange, rotoNode, rptsw_shapeList, task, fxsExport, bakeshapes) #=*=*=*=*=*=*==task=related=code======================================== task.setMessage('Creating Layers') task.setProgress(30) taskLength = len(rptsw_shapeList) taskCount = 0.0 #=*=*=*=*=*=*==task=related=code======================================== #======================================================================= # create all layers and shapes inside them #======================================================================= for item in rptsw_shapeList: taskCount += 1.0 x = (taskCount / taskLength) * 10 + 30 task.setProgress(30 + int((taskCount / taskLength) * 20)) #=*=*=*=*=*=*==task=related=code======================================== if cancel: break #=*=*=*=*=*=*==task=related=code======================================== if isinstance(item[0], nuke.rotopaint.Layer): createLayers(item, fRange, rotoNode, rptsw_shapeList, task, fxsExport, bakeshapes) #=================================================================== # reorder layers/shapes #=================================================================== layerlist = [] for item in rptsw_shapeList[::-1]: if item[1].name not in layerlist: #find all parent names layerlist.append(item[1].name) #=*=*=*=*=*=*==task=related=code======================================== task.setMessage('Reordering Layer/Shapes') task.setProgress(50) taskLength = len(rptsw_shapeList) taskCount = 0.0 #=*=*=*=*=*=*==task=related=code======================================== for name in layerlist: #=*=*=*=*=*=*==task=related=code======================================== task.setProgress(50 + int((taskCount / taskLength) * 50)) taskCount += 1.0 if cancel: break #=*=*=*=*=*=*==task=related=code======================================== data = [] parentElement = [] for item in rptsw_shapeList[::-1]: if item[1].name == name: #all items from same parent for itemx in fxsExport.findall('.//*'): if itemx.get('label') != None: if item[0].name == itemx.get('label'): if itemx not in data: data.append( itemx ) #locate the elements of that parent for itemx in fxsExport.findall('.//*'): if itemx.get('label') == name: obj = itemx.findall("Properties/Property") for item in obj: if item.get('id') == "objects": parentElement.append(item) break for n in range(len(data)): parentElement[0][n] = data[n] #=================================================================== # end of reorder layers/shapes #=================================================================== else: nuke.message('Shape Exporter is for Nuke v7 only') #=*=*=*=*=*=*==task=related=code======================================== if cancel: nuke.delete(rotoNode) return #=*=*=*=*=*=*==task=related=code======================================== #=========================================================================== # EXPORT the fxs file #=========================================================================== path = os.getenv('FXSEXPORTPATH') if path == None: path = nuke.getFilename('Save the .fxs file', '*.fxs', "fxsExport.fxs") if path == None: if nuke.GUI: nuke.message( 'Aborting Script, you need to save the export to a file') return else: base = os.path.split(path)[0] ext = os.path.split(path)[1][-4:] #================================================================== # adds extension if not present on the filename #================================================================== if ext != ".fxs": ext = ext + ".fxs" path = os.path.join(base, ext) else: print "Saving file to: %s" % path indent(fxsExport) ET.ElementTree(fxsExport).write(path) nuke.delete(rotoNode) task.setProgress(100) print "Time elapsed: %s seconds" % (time.time() - start_time)
def render(node=None): nodes = [] fparams = dict() if node is not None: # Render only specified node: nodes.append(node) renderNodes(nodes, fparams, False) return # Store minimum and maximum frames to show in dialog hasafanasynodes = False framefirst_min = None framefirst_max = None framelast_min = None framelast_max = None framespertask_min = None framespertask_max = None framesequential_min = None framesequential_max = None selectednodes = nuke.selectedNodes() selectednodes.sort(None, getNodeName) for node in selectednodes: if node.Class() == AfanasyNodeClassName \ or node.Class() == RenderNodeClassName \ or node.Class() == DailiesNodeClassName: nodes.append(node) # Check for minimum and maximum if node.Class() == AfanasyNodeClassName: hasafanasynodes = True framefirst = int(node.knob('framefirst').value()) framelast = int(node.knob('framelast').value()) framespertask = int(node.knob('framespertask').value()) framesequential = int(node.knob('framesequential').value()) else: framefirst = nuke.root().firstFrame() framelast = nuke.root().lastFrame() framespertask = 1 + int((framelast - framefirst) / 10.0) framesequential = 1 if framefirst_min is None: framefirst_min = framefirst else: framefirst_min = min(framefirst_min, framefirst) if framefirst_max is None: framefirst_max = framefirst else: framefirst_max = max(framefirst_max, framefirst) if framelast_min is None: framelast_min = framelast else: framelast_min = min(framelast_min, framelast) if framelast_max is None: framelast_max = framelast else: framelast_max = max(framelast_max, framelast) if framespertask_min is None: framespertask_min = framespertask else: framespertask_min = min(framespertask_min, framespertask) if framespertask_max is None: framespertask_max = framespertask else: framespertask_max = max(framespertask_max, framespertask) if framesequential_min is None: framesequential_min = framesequential else: framesequential_min = min(framesequential_min, framesequential) if framesequential_max is None: framesequential_max = framesequential else: framesequential_max = max(framesequential_max, framesequential) if len(nodes) < 1: nuke.message( 'No nodes to render found.\n' 'Select "%s" or "%s" node(s) to render.' % (AfanasyNodeClassName, RenderNodeClassName) ) return nodesstring = nodes[0].name() if len(nodes) > 1: for i in range(1, len(nodes)): nodesstring += ' ' + nodes[i].name() # Construct frame ranges: if framefirst_min != framefirst_max: framefirst = '%s..%s' % (framefirst_min, framefirst_max) else: framefirst = framefirst_min if framelast_min != framelast_max: framelast = '%s..%s' % (framelast_min, framelast_max) else: framelast = framelast_min if framespertask_min != framespertask_max: framespertask = '%s..%s' % (framespertask_min, framespertask_max) else: framespertask = framespertask_min if framesequential_min != framesequential_max: framesequential = '%s..%s' % (framesequential_min, framesequential_max) else: framesequential = framesequential_min # Dialog: panel = nuke.Panel('Afanasy Render') panel.addSingleLineInput('Nodes:', nodesstring) panel.addSingleLineInput('First Frame:', framefirst) panel.addSingleLineInput('Last Frame:', framelast) panel.addSingleLineInput('Frames Per Task:', framespertask) panel.addSingleLineInput('Frame Sequential:', framesequential) if hasafanasynodes: panel.addBooleanCheckBox('Store Frames Settings', 0) panel.addBooleanCheckBox('Start Paused', 0) panel.addButton("Cancel") panel.addButton("OK") result = panel.show() if not result: return # Check for selected nodes: nodesstring = panel.value('Nodes:') selectednodes = nodesstring.split() nodes = [] for name in selectednodes: node = nuke.toNode(name) if node is None: nuke.message('Node "%s" not found.' % name) return if node.Class() == AfanasyNodeClassName \ or node.Class() == RenderNodeClassName \ or node.Class() == DailiesNodeClassName: nodes.append(node) if len(nodes) < 1: nuke.message( 'No nodes to render found.\n' 'Select "%s" or "%s" node(s) to render.' % (AfanasyNodeClassName, RenderNodeClassName) ) return # Get parameters: sframefirst = str(panel.value('First Frame:')) sframelast = str(panel.value('Last Frame:')) sframespertask = str(panel.value('Frames Per Task:')) sframesequential = str(panel.value('Frame Sequential:')) storeframes = False if hasafanasynodes: storeframes = int(panel.value('Store Frames Settings')) if panel.value('Start Paused'): fparams['startpaused'] = 1 # Check frame range was set: if sframefirst.find('..') == -1: try: framefirst = int(sframefirst) except: nuke.message('Invalid first frame "%s"' % sframefirst) return fparams['framefirst'] = framefirst if sframelast.find('..') == -1: try: framelast = int(sframelast) except: nuke.message('Invalid last frame "%s"' % sframelast) return fparams['framelast'] = framelast if sframespertask.find('..') == -1: try: framespertask = int(sframespertask) except: nuke.message('Invalid frames per task "%s"' % sframespertask) return fparams['framespertask'] = framespertask if sframesequential.find('..') == -1: try: framesequential = int(sframesequential) except: nuke.message('Invalid frames sequential "%s"' % sframesequential) return fparams['framesequential'] = framesequential if not checkFrameRange(framefirst, framelast, 1, framespertask): return # Render selected nodes: renderNodes(nodes, fparams, storeframes)
def renderNodes(nodes, fparams, storeframes): global af af = __import__('af', globals(), locals(), []) scene_path = nuke.root().name() if scene_path == 'Root': scene_path = os.getenv('NUKE_AF_TMPSCENE', 'tmp') scene_path = os.path.abspath(scene_path) scene_name = os.path.basename(scene_path) ftime = time.time() tmp_suffix = time.strftime('.%m%d-%H%M%S-') + str(ftime - int(ftime))[2:5] tmp_scene_path = scene_path + tmp_suffix jobsparameters = [] for node in nodes: newjobparameters = [] newjobparameters = None if node.Class() == AfanasyNodeClassName: oldparams = dict() for key in fparams: oldparams[key] = node.knob(key).value() node.knob(key).setValue(fparams[key]) newjobparameters = getJobsParameters(node, scene_name, dict()) if newjobparameters is None: return if not storeframes: for key in oldparams: node.knob(key).setValue(oldparams[key]) if node.Class() == RenderNodeClassName \ or node.Class() == DailiesNodeClassName: blocksparameters = [] bparams = BlockParameters(None, node, False, '', fparams) if not bparams.valid: return blocksparameters.append(bparams) jobparams = JobParameters(None, scene_name, blocksparameters, fparams) if not jobparams.valid: return newjobparameters = [jobparams] if newjobparameters is None: if VERBOSE: print('Job(s) parameters generation error on "%s"' % node.name()) return if len(newjobparameters) > 0: jobsparameters.extend(newjobparameters) jobs = [] for jobparams in jobsparameters: if jobparams.tmpscene: job = jobparams.genJob(tmp_scene_path) else: job = jobparams.genJob(scene_path) if job is None: if VERBOSE: print('Job generatiton error on "%s"' % jobparams.nodename) return jobs.append(job) if len(jobs) == 0: nuke.message('No jobs generated.') return cgrupathmap = __import__('cgrupathmap', globals(), locals(), []) pm = cgrupathmap.PathMap(UnixSeparators=True, Verbose=False) # Store scene modified state changed = nuke.modified() # Save all generated jobs scenes for i in range(len(jobs)): scene_path = jobsparameters[i].scene_path # Apply paths mapping if enables and rendering to temporary scene if jobsparameters[i].pathsmap and pm.initialized and jobsparameters[i].tmpscene: pm_scene_path = scene_path + '.pm' nuke.scriptSave(pm_scene_path) pm.toServerFile( pm_scene_path, scene_path, SearchStrings=['file ', 'font ', 'project_directory '], Verbose=False ) os.remove(pm_scene_path) else: nuke.scriptSave(scene_path) # Send job to server if not jobs[i].send()[0]: nuke.message('Unable to send job to server.') os.remove(scene_path) break # This is needed if ocassionaly user sending to render thousands of nodes time.sleep(0.1) # Restore scene modified state nuke.modified(changed)
def start(): import math import nuke import nukescripts import threading class MergeTransformsPanel(nukescripts.PythonPanel): def __init__(self): nukescripts.PythonPanel.__init__(self, 'Merge Transforms') # CREATE KNOBS self.first = nuke.Int_Knob('first', 'First Frame') self.first.setValue(int(nuke.root()['first_frame'].value())) self.last = nuke.Int_Knob('last', 'Last Frame') self.last.setValue(int(nuke.root()['last_frame'].value())) self.forceCP = nuke.Boolean_Knob('force_cp', 'Force Merge as CornerPin') self.forceCP.setFlag(nuke.STARTLINE) self.forceCP.setTooltip( 'Tool will merge transforms a a new Transform if possible, or Cornerpin if necessary.' '\nChecking this box will force a corner pin output') self.forceMatrix = nuke.Boolean_Knob('force_matrix', 'CornerPin as extra_matrix') self.forceMatrix.setTooltip( "Uses the cornerpin's extra_matrix to recreate the transform rather than the corners" ) self.forceMatrix.setEnabled(False) self.forceMatrix.setFlag(nuke.STARTLINE) # ADD KNOBS for k in (self.first, self.last, self.forceCP, self.forceMatrix): self.addKnob(k) def knobChanged(self, knob): # ONLY SHOW FORCEMATRIX IF CORNERPIN IS ON if knob is self.forceCP: self.forceMatrix.setEnabled(self.forceCP.value()) # definitions def check_classes(nodes, allowed_classes): valid = True for n in nodes: if n.Class() not in allowed_classes: nuke.message("Please select only supported Nodes:" + ', '.join(allowed_classes)) valid = False break return valid # Matrix to CornerPin rarely fails def sort_nodes(node_list): # Sorts selected nodes by number of parents of an allowed class nodes_in_list = 0 sorted_list = [] for n in node_list: has_parents = True number_of_nodes = 1 list_of_nodes = [n] # we count how many parents the node has while has_parents: p = n.input(0) if p: if p['selected'].value(): n = p number_of_nodes += 1 list_of_nodes.append(n) else: has_parents = False else: has_parents = False # the node with the biggest number of parents is our last node if number_of_nodes > nodes_in_list: nodes_in_list = number_of_nodes sorted_list = list_of_nodes # We want our first node first though, so we reverse the list sorted_list.reverse() return sorted_list def print_matrix4(m): row = '| ' + 4 * '{: .4f} ' + '|' print row.format(m[0], m[4], m[8], m[12]) print row.format(m[1], m[5], m[9], m[13]) print row.format(m[2], m[6], m[10], m[14]) print row.format(m[3], m[7], m[11], m[15]) def decompose_matrix(m, center_x=0, center_y=0): # Solve Translation vector = nuke.math.Vector3(center_x, center_y, 0) vector_trans = m.transform(vector) translate_x = vector_trans[0] - center_x translate_y = vector_trans[1] - center_y # Solve Rotation/Scale/Skew # Skew Y is never solved, will be reflected in Rotation instead. delta = (m[0] * m[5]) - (m[4] * m[1]) r = pow(m[0], 2) + pow(m[1], 2) rotation = math.degrees(math.atan2(m[1], m[0])) scale_x = math.sqrt(r) scale_y = delta / scale_x skew_x = (m[0] * m[4] + m[1] * m[5]) / delta return translate_x, translate_y, rotation, scale_x, scale_y, skew_x def matrix_to_cornerpin(matrix, cornerpin_node, frame, width, height): 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 xrange(2): cornerpin_node['to1'].setValueAt(v1[i], frame, i) cornerpin_node['to2'].setValueAt(v2[i], frame, i) cornerpin_node['to3'].setValueAt(v3[i], frame, i) cornerpin_node['to4'].setValueAt(v4[i], frame, i) return def get_matrix_at_frame(node, frame): matrix = None if node.Class() == 'Transform' or node.Class() == 'Tracker4': k = node.knob('matrix') context = nuke.OutputContext() context.setFrame(frame) matrix = k.value(context) elif node.Class() == 'CornerPin2D': # Calculate 'to' matrix to_matrix = nuke.math.Matrix4() to1x = node['to1'].getValueAt(frame)[0] to1y = node['to1'].getValueAt(frame)[1] to2x = node['to2'].getValueAt(frame)[0] to2y = node['to2'].getValueAt(frame)[1] to3x = node['to3'].getValueAt(frame)[0] to3y = node['to3'].getValueAt(frame)[1] to4x = node['to4'].getValueAt(frame)[0] to4y = node['to4'].getValueAt(frame)[1] to_matrix.mapUnitSquareToQuad(to1x, to1y, to2x, to2y, to3x, to3y, to4x, to4y) # Calculate 'to' matrix from_matrix = nuke.math.Matrix4() from1x = node['from1'].getValueAt(frame)[0] from1y = node['from1'].getValueAt(frame)[1] from2x = node['from2'].getValueAt(frame)[0] from2y = node['from2'].getValueAt(frame)[1] from3x = node['from3'].getValueAt(frame)[0] from3y = node['from3'].getValueAt(frame)[1] from4x = node['from4'].getValueAt(frame)[0] from4y = node['from4'].getValueAt(frame)[1] from_matrix.mapUnitSquareToQuad(from1x, from1y, from2x, from2y, from3x, from3y, from4x, from4y) # Calculate the extra matrix k = node.knob('transform_matrix') values = k.getValueAt(frame) extra_matrix = nuke.math.Matrix4() for i in xrange(len(values)): extra_matrix[i] = values[i] extra_matrix.transpose() matrix = extra_matrix * (to_matrix * from_matrix.inverse()) if node['invert'].getValueAt(frame): matrix = matrix.inverse() return matrix def fuse_transforms(transform_list, first, last, cornerpin=False, force_matrix=False): # Set Threading task = nuke.ProgressTask("Merging Transforms") task.setMessage("Checking Settings") # Check if we only have Cornerpins in the list for n in transform_list: if n.Class() == 'CornerPin2D': cornerpin = True # Our nodes resolution might be useful too height = transform_list[0].height() width = transform_list[0].width() # Create the node to receive the baked transformations if cornerpin: new_node = nuke.nodes.CornerPin2D( inputs=[transform_list[0].input(0)], xpos=transform_list[0]['xpos'].value() + 100, ypos=transform_list[0]['ypos'].value(), label='Merged Transform') new_node['from1'].setValue(0, 0) new_node['from1'].setValue(0, 1) new_node['from2'].setValue(width, 0) new_node['from2'].setValue(0, 1) new_node['from3'].setValue(width, 0) new_node['from3'].setValue(height, 1) new_node['from4'].setValue(0, 0) new_node['from4'].setValue(height, 1) if not first == last: # More than one frame, enable animation if not force_matrix: new_node['to1'].setAnimated() new_node['to2'].setAnimated() new_node['to3'].setAnimated() new_node['to4'].setAnimated() else: new_node['transform_matrix'].setAnimated() else: new_node = nuke.nodes.Transform( inputs=[transform_list[0].input(0)], xpos=transform_list[0]['xpos'].value() + 100, ypos=transform_list[0]['ypos'].value(), label='Merged Transform') new_node['center'].setValue(width / 2, 0) new_node['center'].setValue(height / 2, 1) if not first == last: # More than one frame, enable animation new_node['translate'].setAnimated() new_node['rotate'].setAnimated() new_node['scale'].setAnimated() new_node['skewX'].setAnimated() task.setMessage("Merging transforms") # We need the calculation for each frame try: for frame in xrange(first, last + 1): if task.isCancelled(): break current_matrix = get_matrix_at_frame(transform_list[0], frame) print 'Calculating Frame: {}'.format(frame) print_matrix4(current_matrix) # We merge the nodes 2 by two for i in range(1, len(transform_list)): # Access the matrix knobs the next transformation transform_matrix = get_matrix_at_frame( transform_list[i], frame) print 'x' print_matrix4(transform_matrix) current_matrix = transform_matrix * current_matrix print '=' print_matrix4(current_matrix) if cornerpin: if force_matrix: current_matrix.transpose() for i in xrange(16): new_node.knob('transform_matrix').setValueAt( current_matrix[i], frame, i) else: matrix_to_cornerpin(current_matrix, new_node, frame, width, height) else: translate_x, translate_y, rotation, scale_x, scale_y, skew_x = decompose_matrix( current_matrix, width / 2, height / 2) new_node['translate'].setValueAt(translate_x, frame, 0) new_node['translate'].setValueAt(translate_y, frame, 1) new_node['rotate'].setValueAt(rotation, frame) new_node['scale'].setValueAt(scale_x, frame, 0) new_node['scale'].setValueAt(scale_y, frame, 1) new_node['skewX'].setValueAt(skew_x, frame) # set thread progress task.setProgress(int( (frame - first) / ((last - first) * 0.01))) except: raise finally: task.setProgress(100) del task # start of procedure nodes = nuke.selectedNodes() if len(nodes) < 2: return valid_nodes = check_classes(nodes, ['Transform', 'CornerPin2D', 'Tracker4']) if valid_nodes: transform_list = sort_nodes(nodes) else: return 0 # We check that we have at least 2 transforms, otherwise no point in merging if len(transform_list) < 2: nuke.message("You need at least 2 transforms selected") return 0 elif len(transform_list) != len(nodes): nuke.message("Please make sure all nodes form a single Branch") return 0 p = MergeTransformsPanel() if p.showModalDialog(): first = p.first.value() last = p.last.value() cornerpin = p.forceCP.value() force_matrix = p.forceMatrix.value() exec_thread = threading.Thread( None, fuse_transforms(transform_list, first, last, cornerpin, force_matrix)) exec_thread.start()
def showDialog( self ): result = nukescripts.PythonPanel.showModalDialog( self ) if result: # User Input Value inputPath = "/All/"+self.project.value()+'/'+self.scene.value()+'/'+ \ self.camera.value()+'/STUFF/'+self.department.value()+'/'+ \ self.folder.value()+'/*'+self.key.value()+'*/' # Via InputPath search All Correct Path searchPath = glob.glob(inputPath) searchPath.sort() # Remove Void Folder for i in searchPath: if glob.glob(i+'*') == []: searchPath.remove(i) # Folder Last Version if self.lastversion.value(): folderPath = [] lastFolderPath = [] for i in searchPath: t = i.split('_'+self.department.value()).pop(0) folderPath.append(t) folderPath = list(set(folderPath)) folderPath.sort() for i in folderPath: lastFolderPath.append(max(glob.glob(i+'*'+self.key.value()+'*'))) searchPath = lastFolderPath # Define xPos is ReadNode x position in the NodeGraph # Define clip is each ReadNode number of AppendclipNode xPos = 0 clip = 0 # Need AppendClipNode if self.appendclip.value(): # Create AppendclipNode appendClip = nuke.createNode('AppendClip',inpanel=False) appendClip.setXYpos(len(searchPath)*50,500) # Create ReadNodes in the loop for i in searchPath: # fileList is each Folder's Files fileList = glob.glob(i+'/*') fileList.sort() # Remove the Error file for i in fileList: if len(i.split('.'))!=3 or len(i.split('.').pop(1)) != 4 or i.split('.').pop(1).isdigit() is False : fileList.remove(i) # Calculate First Frame and Last Frame frontNum = str(int(min(fileList).split('.').pop(1)) + self.frmplus.value()) backNum = str(int(max(fileList).split('.').pop(1)) - self.frmminus.value()) # fileName is fullname of the ReadNode fileName = fileList[0].split('.').pop(0)+'.%04d.'+fileList[0].split('.').pop() # Create ReadNode creatRead=nuke.createNode("Read","file {"+fileName+" "+frontNum+"-"+backNum+"}", inpanel = False) creatRead.setXYpos(xPos,1) xPos=xPos+100 # link to AppendclipNode sc=nuke.selectedNode() appendClip.setInput(clip,sc) clip=clip+1 # Needn't AppendClipNode else: # Create ReadNodes in the loop for i in searchPath: # fileList is each Folder's Files fileList = glob.glob(i+'/*') fileList.sort() # Remove the Error file for i in fileList: if len(i.split('.'))!=3 or len(i.split('.').pop(1)) != 4 or i.split('.').pop(1).isdigit() is False : fileList.remove(i) # Calculate First Frame and Last Frame frontNum = str(int(min(fileList).split('.').pop(1)) + self.frmplus.value()) backNum = str(int(max(fileList).split('.').pop(1)) - self.frmminus.value()) # fileName is fullname of the ReadNode fileName = fileList[0].split('.').pop(0)+'.%04d.'+fileList[0].split('.').pop() # Create ReadNode creatRead=nuke.createNode("Read","file {"+fileName+" "+frontNum+"-"+backNum+"}", inpanel = False) creatRead.setXYpos(xPos,1) xPos=xPos+100 # Show the message length=len(searchPath) nuke.message(str(length)+'Reads')
import nuke nodes = nuke.selectedNodes() if nodes and nodes[-1].Class() == "BackdropNode": #print bdNode.Class() #nukescripts.clear_selection_recursive() bdNode = nodes[-1] bdNode.selectNodes() nodesInBd = nuke.selectedNodes() viewerNodes = [node for node in nodesInBd if node.Class() == "Viewer"] nodesInBd = [node for node in nodesInBd if not node.Class() == "Viewer"] nukescripts.clear_selection_recursive() [node['selected'].setValue('True') for node in nodesInBd] #map(lambda viewer: viewer['selected'].setValue('False'), viewerNodes) #[viewer['selected'].setValue('False') for viewer in viewerNodes] #print viewerNodes #print [node.name() for node in nodesInBd] else: nuke.message("Please select valid nodes!")
def smartProjectSetter(projectPath, scriptPath, renderPath): projectPath = projectPath scriptPath = scriptPath renderPath = renderPath if os.path.isdir(projectPath): #setting up p = createPanel(projectPath) if p.show(): userPath = p.value('create new script: ') #convert whitespace back userPath = userPath.replace("**", " ") artist = p.value('artist: ') scriptname = p.value('script name: ') scriptname = scriptname.replace(" ", "_") scriptname = scriptname.replace("@", "_") projectComment = p.value("comment (optional): ") # # actions # # 1 open recent # 2 open latest script # 3 create project #01 open recent recentFile = p.value("open recent file") #cancel button pressed if recentFile is None: recentFile = "---OpenRecentFile---" if recentFile != "---OpenRecentFile---": def openRecent(): nuke.scriptOpen(recentFile) return True def thread_dispatch(): return nuke.executeInMainThreadWithResult(openRecent, ()) thread.start_new_thread(thread_dispatch, ()) #02 open latest script latestScript = p.value("open latest script") #cancel button pressed if latestScript is None: latestScript = "---OpenLatestScript---" if latestScript != "---OpenLatestScript---": def openRecent(): nuke.scriptOpen(latestScript) return True def thread_dispatch(): return nuke.executeInMainThreadWithResult(openRecent, ()) thread.start_new_thread(thread_dispatch, ()) #03 create project if userPath != "---ChooseProject---" and userPath != " -------------------- ": #convert whitespace back if scriptname != "": t = getTime() #create Folder projectPath = getSmartSettings("@projectPath") project = userPath scriptPath = getSmartSettings("@scriptPath") #setting script and render folder scriptFolder = projectPath + "/" + project + "/" + scriptPath + "/" + artist + "/" + scriptname scriptsDir = scriptFolder + "/scripts" footageFolderPath = scriptFolder + "/_footage" trkFolder = scriptFolder + "/trk" assetsFolder = scriptFolder + "/assets" referencesFolder = scriptFolder + "/references" fullScriptPath = scriptsDir + "/" + scriptname + "@" + t + ".nk" renderFolder = projectPath + "/" + project + "/" + renderPath + "/" + artist + "/" + scriptname #create scriptFolder, renderFolder, toFolder createFolders(scriptFolder) createFolders(scriptsDir) createFolders(footageFolderPath) createFolders(trkFolder) createFolders(assetsFolder) createFolders(referencesFolder) createFolders(renderFolder) #set root name #when starting nuke and setting up project nuke.knobDefault("Root.name", fullScriptPath) #when setting up new project in between nuke.root()['name'].setValue(fullScriptPath) if projectComment != "": #write comment in root.label and create text file in project folder #when starting nuke and setting up project nuke.knobDefault("Root.label", projectComment) #when setting up new project in between nuke.root()['label'].setValue(projectComment) #create txt file fobj_out = open(scriptFolder + "/_projectnote.txt", "w") fobj_out.write(projectComment) fobj_out.close() smartSaver() else: if (scriptPath == "---" and renderPath == "---" and projectPath == "---"): nuke.message( "Welcome to smart. Please make sure to insert all the inputs correctly in order to make .smart work correctly" ) else: nuke.message( "Could not find the project path. Make sure that the path is set correctly" ) smartSetter()
def BackdropResize(): '''main function''' nodes = nuke.selectedNodes() if len(nodes) <= 0: nuke.message("Select some nodes goddamnit") print "Abort" elif len([b for b in nodes if b.Class() == 'BackdropNode']) <= 0: nuke.message("Gotta include a Backdrop Node, man") print "Abort" else: # Prompt p = nuke.Panel("Resize %s" % bdFind(nodes).name()) p.addEnumerationPulldown('Mode', '"Fit to Selection" "Manual Scaling"') # p.addBooleanCheckBox('Fit to Selection', True) p.addButton('Cancel') p.addButton('Resize!') p.setWidth(len(p.title()) * 12) if p.show(): mode_sel = p.value('Mode') # Find Biggest Backdrop node to resize node_bd = bdFind(nodes) # Fit to Selection if mode_sel == "Fit to Selection": new_size = bdSizeFit(nodes, node_bd) resize(node_bd, new_size) print "%s Resized to Fit Selection" % node_bd.name() # Manual Scaling elif mode_sel == "Manual Scaling": # Second Prompt psub = nuke.Panel("Resize %s" % bdFind(nodes).name()) psub.addExpressionInput('Width', 1) # average node width: 80 psub.addExpressionInput('Height', 1) #average node height: 74 psub.addBooleanCheckBox('From Center', True) psub.addButton('Cancel') psub.addButton('Resize!') psub.setWidth(len(p.title()) * 12) if psub.show(): input_w = psub.value('Width') input_h = psub.value('Height') input_c = psub.value('From Center') new_size = bdSizeScale(node_bd, input_w, input_h, input_c) resize(node_bd, new_size) print "%s Resized with input values" % node_bd.name() else: print "Operation Cancelled"
def saveImage (): ### creating panel and assign buttons ef = nuke.Panel("saveImage As...... by satheesh-r", 420) ef.addFilenameSearch("Save Image As:\nchoose path & file type", "") ef.addButton("cancel") ef.addEnumerationPulldown('channels', "rgb rgba all") ef.addEnumerationPulldown('Exr data type', "16bit-half 32bit-float") ef.addButton("ok") window=ef.show() exrtype = ef.value('Exr data type') channel = ef.value('channels') path = ef.value("Save Image As:\nchoose path & file type") fileType = path.split('.')[-1] if window == 0 : return ### getting path from user input if path == "": nuke.message('no file path selected ') if path == "": return ### getting active node curViewer = nuke.activeViewer() curNode = curViewer.node() acticeVinput = curViewer.activeInput() curN = curNode.input(acticeVinput) ### creating temp write w = nuke.createNode("Write") w.setName("tempWrite") w.setInput(0, curN) w['file'].setValue(path) ### if file type is jpg if fileType == 'jpg' : w['_jpeg_sub_sampling'].setValue(2) w['_jpeg_quality'].setValue(1) ### if file type is exr if fileType == 'exr' : w['datatype'].setValue(exrtype) w['compression'].setValue(2) w['metadata'].setValue(0) if channel == 'rgba' : w['channels'].setValue('rgba') if channel == 'all' : w['channels'].setValue('all') ### setting current frame for render result = nuke.frame() if result =="": result = result ### execute write node nuke.execute(nuke.selectedNode(), (int(result)), result) name = w.knob('file').value() nukescripts.node_delete(popupOnError=True) ### create Read node r = nuke.createNode("Read") r['file'].setValue(name) result = nuke.frame() r['first'].setValue(int(result)) r['last'].setValue(int(result)) r['xpos'].setValue( 200 ) if fileType == "": return
i.knob(attr).setValue(val) print i.name()+': ', attr,'>>' , val # replace footage path import glob old_ver = 'v001t01' new_ver = 'v001t02' nodes = nuke.selectedNodes() replaced_file = 'Result: \n' for i in nodes: try: getval = i.knob('file').getValue() except AttributeError: continue if not old_ver in getval: continue else: new_file = getval.replace(old_ver, new_ver) search_name = new_file.replace('%04d.exr', '????.*') if glob.glob(search_name): i.knob('file').setValue(new_file) replaced_file = replaced_file + 'Update: ' + getval.split('/')[-1].split('.')[0] + ' >> ' + new_ver + '\n' else: print new_file.split('/')[-1],'does not exists', '\n' if replaced_file: nuke.message(replaced_file)
def freezeWarp_v2(): try: node = nuke.selectedNode() if node.Class() not in ('SplineWarp3'): if nuke.GUI: nuke.message('Unsupported node type. Node must be SplineWarp') return except: if nuke.GUI: nuke.message('Select a SplineWarp Node') return shapeList = [] curves = node['curves'] nodeRoot = curves.rootLayer shapeList = fws_walker(nodeRoot, shapeList) #=========================================================================== # panel setup #=========================================================================== p = nukescripts.panels.PythonPanel("Freeze Splinewarp") k = nuke.Int_Knob("freezeframe", "Freezeframe") k.setFlag(nuke.STARTLINE) k.setTooltip("Set the frame to freeze the shapes positions") p.addKnob(k) k.setValue(nuke.root().firstFrame()) k = nuke.Enumeration_Knob('outputcurve', 'Curves to Freeze', ['A', 'B']) k.setFlag(nuke.STARTLINE) k.setTooltip("Freeze all the curves on the A or B output") p.addKnob(k) k = nuke.Boolean_Knob("mt", "MultiThread") k.setFlag(nuke.STARTLINE) k.setTooltip( "This will speed up the script but without an accurate progress bar") p.addKnob(k) k.setValue(True) k = nuke.Boolean_Knob("exp", "Use Expression to Freeze") k.setFlag(nuke.STARTLINE) k.setTooltip( "Instead of deleting keyframes, it will use expressions on the shapes and also add a frame control on the node" ) p.addKnob(k) k.setValue(True) k = nuke.Boolean_Knob("fh", "Create FrameHold") k.setFlag(nuke.STARTLINE) k.setTooltip( "This will create a Framehold Node and set it to the Freezeframe value, if you use expressions mode it will be linked" ) p.addKnob(k) k.setValue(True) if not checkAB(shapeList): p.addKnob( nuke.Text_Knob( "", "", "\nWARNING: your node has only\ncurves on A or B outputs\n")) #=========================================================================== # end of panel setup #=========================================================================== result = p.showModalDialog() if result == 0: return # Canceled freezeFrame = p.knobs()["freezeframe"].value() ab = 1.0 if p.knobs()["outputcurve"].value() == "A" else 2.0 exp = p.knobs()["exp"].value() mt = p.knobs()["mt"].value() if nuke.NUKE_VERSION_MAJOR > 6: #======================================================================= # task setup #======================================================================= global cancel cancel = False task = nuke.ProgressTask('Freeze SplineWarp') n = 0 #======================================================================= # task end #======================================================================= if exp: names = [] for i in node.allKnobs(): names.append(i.name()) if "FreezeFrame" not in names: #avoid creating the pane if it already exists tab = nuke.Tab_Knob('FreezeFrame') node.addKnob(tab) ff = nuke.Int_Knob('fframe', "Freeze Frame") node.addKnob(ff) try: ff.setValue(freezeFrame) except: pass for shape in shapeList: if cancel: return task.setMessage('Processing ' + shape.name) task.setProgress((int(n / len(shapeList) * 100))) if mt: threading.Thread(None, expressionLock, args=(shape, ab, freezeFrame, node, task)).start() else: expressionLock(shape, ab, freezeFrame, node, task) n += 1 else: for shape in shapeList: if cancel: return task.setMessage('Processing ' + shape.name) task.setProgress((int(n / len(shapeList) * 100))) if mt: threading.Thread(None, keyFreeze, args=(shape, ab, freezeFrame, task)).start() else: keyFreeze(shape, ab, freezeFrame, task) n += 1 #=========================================================================== # join existing threads (to wait completion before continue) #=========================================================================== main_thread = threading.currentThread() for t in threading.enumerate(): if t is main_thread: continue t.join() curves.changed() else: nuke.message( 'This version is for Nuke v7, use v1.1 with Nuke v6.3 from Nukepedia' ) fh = p.knobs()["fh"].value() if fh: framehold = nuke.nodes.FrameHold() if exp: framehold["first_frame"].setExpression(node.name() + ".fframe") else: framehold.knob("first_frame").setValue(freezeFrame) #======================================================================= # some layout beautyfication #======================================================================= framehold["xpos"].setValue(node["xpos"].getValue() - 100) framehold["ypos"].setValue(node["ypos"].getValue() - 80) dot = nuke.nodes.Dot() dot["xpos"].setValue(node["xpos"].getValue() + 35) dot["ypos"].setValue(framehold["ypos"].getValue() + 11) set_inputs(node, dot) set_inputs(dot, framehold) label = "FreezeF: [value fframe]" if exp else "FreezeF:" + str(freezeFrame) node.knob('label').setValue(label) node.knob('filter').setValue('Mitchell') #less smoother than cubic print "FreezeSplineWarp Finished,", len( shapeList), "shape(s) at frame", freezeFrame
def main(): current_path = nuke.root()["name"].getValue() nuke.root()["fps"].setValue(25) step_root = current_path.split("nuke")[0] camera_path = os.path.normpath(os.path.join(step_root, "fbx")) obj_path = os.path.normpath(os.path.join(step_root, "obj")) sourceimage = os.path.normpath(os.path.join(step_root, "sourceimages")) try: read_src_dir = max( [x for x in os.listdir(sourceimage) if not "undist" in x]) read_src_path = os.path.join(sourceimage, read_src_dir) except: nuke.message(u"get the sourceimage first!!") read_src_path = '' dist_count = 0 try: read_dist_dir = max( [x for x in os.listdir(sourceimage) if "undist" in x]) read_dist_path = os.path.join(sourceimage, read_dist_dir) dist_count = len([x for x in os.listdir(sourceimage) if "undist" in x]) except: read_dist_path = '' nuke.message(u"doesn't have the export of undistortion") #distortin node dist_dir = os.path.normpath(os.path.join(step_root, "nuke")) try: dist_file = max([ x for x in os.listdir(dist_dir) if "tracking_dist" in x and "auto" not in x ]) dist_path = os.path.join(dist_dir, dist_file) except: nuke.message(u"get the sourceimage first!!") #camera_path try: camera_file = max([x for x in os.listdir(camera_path)]) camera_filepath = os.path.join(camera_path, camera_file).replace("\\", "/") except: camera_filepath = '' #obj_path try: obj_file = max([x for x in os.listdir(obj_path)]) obj_filepath = os.path.join(obj_path, obj_file).replace("\\", "/") except: obj_filepath = '' #first_block_______________________________________________________________________________________________ read_jpg = nuke.createNode("Read") read_jpg['name'].setValue("source_jpg") if read_src_path: jpg_file = [ x for x in nuke.getFileNameList(read_src_path) if "jpg" in x or "jpeg" in x ][0] jpg_path = os.path.join(read_src_path, jpg_file) else: jpg_path = '' read_jpg['file'].fromUserText(jpg_path) read_jpg["xpos"].setValue(-301.0) read_jpg["ypos"].setValue(-117.0) basic_format = read_jpg["format"].toScript() nuke.addFormat('%s %s' % (basic_format, "basic_res")) reformat_jpg = nuke.createNode("Reformat") reformat_jpg["resize"].setValue(0) reformat_jpg.setInput(0, read_jpg) reformat_jpg["black_outside"].setValue(1) reformat_jpg["xpos"].setValue(-301.0) reformat_jpg["ypos"].setValue(19.0) nuke.nodePaste(dist_path) dist_node = nuke.selectedNodes()[0] dist_node["dst_hide"].setValue(1) dist_node["reverse"].setValue(1) dist_node["background"].setValue(0) dist_node["xpos"].setValue(-301.0) dist_node["ypos"].setValue(76.0) res = dist_node["name"].getValue().split("_")[-1] resx = res.split("x")[0] resy = res.split("x")[1] nuke.addFormat('%s %s %s' % (resx, resy, "current_res")) reformat_jpg["format"].setValue("current_res") dist_node.setInput(0, reformat_jpg) write_first = nuke.createNode("Write") version_first = dist_count + 1 dist_folder = read_src_dir + "_undist_v%02d" % version_first dist_name = "{}.%04d.jpg".format(dist_folder) first_write_path = os.path.join(sourceimage, dist_folder, dist_name).replace("\\", "/") write_first['file'].setValue(first_write_path) write_first["file_type"].setValue("jpeg") write_first["_jpeg_quality"].setValue(1) write_first.setInput(0, dist_node) write_first["xpos"].setValue(-301.0) write_first["ypos"].setValue(184.0) bdn_1 = nuke.createNode("BackdropNode") dir(bdn_1) bdn_1["xpos"].setValue(-355.0) bdn_1["ypos"].setValue(-202.0) bdn_1["bdheight"].setValue(461) bdn_1["bdwidth"].setValue(198) bdn_1["label"].setValue( "Undistortion\n\xe5\x8e\xbb\xe9\x99\xa4\xe9\x95\x9c\xe5\xa4\xb4\xe7\x95\xb8\xe5\x8f\x98" ) #second_block_______________________________________________________________________________________________ read_undist = nuke.createNode("Read") read_undist['name'].setValue("undist_file") undist_file = nuke.getFileNameList(read_dist_path)[0] undist_path = os.path.join(read_dist_path, undist_file) read_undist['file'].fromUserText(undist_path) read_undist["xpos"].setValue(0) read_undist["ypos"].setValue(-117.0) nuke.nodePaste(dist_path) dist_node2 = nuke.selectedNodes()[0] dist_node2["dst_hide"].setValue(1) dist_node2["reverse"].setValue(0) dist_node2["background"].setValue(0) dist_node2["xpos"].setValue(0) dist_node2["ypos"].setValue(19) dist_node2.setInput(0, read_undist) reformat_undist = nuke.createNode("Reformat") reformat_undist["resize"].setValue(0) reformat_undist.setInput(0, dist_node2) reformat_undist["xpos"].setValue(0) reformat_undist["ypos"].setValue(130) reformat_undist["clamp"].setValue(1) try: reformat_undist["format"].setValue("basic_res") except: reformat_undist["format"].setValue("%s basic_res" % basic_format.split(" ")[-1]) bdn_2 = nuke.createNode("BackdropNode") bdn_2["xpos"].setValue(-55.0) bdn_2["ypos"].setValue(-202.0) bdn_2["bdheight"].setValue(461) bdn_2["bdwidth"].setValue(198) bdn_2["label"].setValue( "Redistortion\n\xe8\xbf\x98\xe5\x8e\x9f\xe9\x95\x9c\xe5\xa4\xb4\xe7\x95\xb8\xe5\x8f\x98" ) #thrid_block_______________________________________________________________________________________________ checker = nuke.createNode("CheckerBoard2") checker["xpos"].setValue(444) checker["ypos"].setValue(-239) readgeo = nuke.createNode("ReadGeo2") readgeo["file"].fromUserText(obj_filepath) readgeo["xpos"].setValue(444) readgeo["ypos"].setValue(-150) readgeo.setInput(0, checker) scene = nuke.createNode("Scene") scene["display"].setValue(1) scene["xpos"].setValue(454) scene["ypos"].setValue(-80) scene.setInput(0, readgeo) cameranode = nuke.createNode("Camera2") cameranode["read_from_file"].setValue(1) cameranode["frame_rate"].setValue(25) cameranode["file"].fromUserText(camera_filepath) cameranode["xpos"].setValue(284) cameranode["ypos"].setValue(31) read_undist2 = nuke.createNode("Read") read_undist2['name'].setValue("undist_file2") read_undist2['file'].fromUserText(undist_path) read_undist2["xpos"].setValue(599) read_undist2["ypos"].setValue(10.0) scanlinerender = nuke.createNode("ScanlineRender") scanlinerender["xpos"].setValue(444) scanlinerender["ypos"].setValue(51) scanlinerender.setInput(2, cameranode) scanlinerender.setInput(0, read_undist2) scanlinerender.setInput(1, scene) nuke.nodePaste(dist_path) dist_node3 = nuke.selectedNodes()[0] dist_node3["reverse"].setValue(0) dist_node3["background"].setValue(0) dist_node3["dst_hide"].setValue(1) dist_node3["xpos"].setValue(444) dist_node3["ypos"].setValue(129) dist_node3.setInput(0, scanlinerender) reformat_undist2 = nuke.createNode("Reformat") reformat_undist2["resize"].setValue(0) reformat_undist2.setInput(0, dist_node3) reformat_undist2["xpos"].setValue(444) reformat_undist2["ypos"].setValue(230) reformat_undist2["clamp"].setValue(1) try: reformat_undist2["format"].setValue("basic_res") except: reformat_undist2["format"].setValue("%s basic_res" % basic_format.split(" ")[-1]) bdn_3 = nuke.createNode("BackdropNode") bdn_3["xpos"].setValue(271) bdn_3["ypos"].setValue(-267.0) bdn_3["bdheight"].setValue(600) bdn_3["bdwidth"].setValue(500)
def __init__(self, afnode, wnode, subblock, prefix, fparams): if VERBOSE == 2: print 'Initializing block parameters for "%s"' % wnode.name() self.wnode = wnode self.valid = True self.subblock = subblock self.prefix = prefix self.framefirst = nuke.root().firstFrame() self.framelast = nuke.root().lastFrame() self.frameinc = 1 self.framespertask = 1 self.maxhosts = -1 self.capacity = -1 self.capacitymin = -1 self.capacitymax = -1 self.hostsmask = None self.hostsmaskexclude = None self.fullrangedepend = 0 self.tmpimage = 1 self.pathsmap = 1 if afnode is not None: self.framefirst = int(afnode.knob('framefirst').value()) self.framelast = int(afnode.knob('framelast').value()) self.frameinc = int(afnode.knob('frameinc').value()) self.framespertask = int(afnode.knob('framespertask').value()) self.maxhosts = int(afnode.knob('maxhosts').value()) self.capacity = int(afnode.knob('capacity').value()) self.capacitymin = int(afnode.knob('capacitymin').value()) self.capacitymax = int(afnode.knob('capacitymax').value()) self.tmpimage = int(afnode.knob('tmpimage').value()) self.pathsmap = int(afnode.knob('pathsmap').value()) self.hostsmask = afnode.knob('hostsmask').value() self.hostsmaskexclude = afnode.knob('hostsmaskexcl').value() self.writename = str(wnode.fullName()) if wnode.Class() == RenderNodeClassName: afcommon = __import__('afcommon', globals(), locals(), []) # Get images files: self.imgfile = '' if nuke.toNode('root').knob('proxy').value(): fileknob = wnode.knob('proxy') else: fileknob = wnode.knob('file') # Get views: views = wnode.knob('views') if views is not None: views = views.value() if views is None or views == '': views = nuke.views() else: views = views.split(' ') else: views = nuke.views() # Iterate views: for view in views: view = view.strip() if not len(view): continue # skip empty view, may be after split(' ') # Check view exists: if not view in nuke.views(): print('Error: Skipping invalid view: "%s"' % view) continue if len(self.imgfile): self.imgfile += ';' # Get thow files for current view and fitst and last frames: octx = nuke.OutputContext() octx.setView(1 + nuke.views().index(view)) octx_framefirst = self.framefirst octx_framelast = self.framelast if octx_framefirst < 0: octx_framefirst = 0 if octx_framelast < 0: octx_framelast = 0 # If frame first and frame last are equal no sequence needed if octx_framefirst == octx_framelast: octx.setFrame(octx_framefirst) self.imgfile += fileknob.getEvaluatedValue(octx) else: # Get files from first and last frames to calculate frames pattern: octx.setFrame(octx_framefirst) images1 = fileknob.getEvaluatedValue(octx) if images1 is None or images1 == '': nuke.message( 'Error:\n%s\nFiles are empty.\nView "%s", frame %d.' % (self.writename, view, self.framefirst)) self.valid = False return octx.setFrame(octx_framelast) images2 = fileknob.getEvaluatedValue(octx) if images2 is None or images2 == '': nuke.message( 'Error:\n%s\nFiles are empty.\nView "%s", frame %d.' % (self.writename, view, self.framelast)) self.valid = False return part1, padding, part2 = afcommon.splitPathsDifference( images1, images2) if padding < 1: nuke.message( 'Error:\n%s\nInvalid files pattern.\nView "%s".' % (self.writename, view)) self.valid = False return self.imgfile += part1 + '@' + '#' * padding + '@' + part2 # Check images folders: for imgfile in self.imgfile.split(';'): folder = os.path.dirname(imgfile) if folder != '': if not os.path.isdir(folder): result = nuke.ask( 'Write Node "%s" Directory\n%s\ndoes not exist.\nCreate it?' % (self.writename, folder)) if result: os.makedirs(folder) if not os.path.isdir(folder): nuke.message('Can`t create folder:\n%s' % folder) self.valid = False else: self.valid = False elif wnode.Class() == DailiesNodeClassName: if VERBOSE: print 'Generating dailies "%s"' % self.writename else: nuke.message('Node type\n"%s"\nis unsendable.' % self.writename) self.valid = False for par in fparams: if fparams[par] is not None: if hasattr(self, par): setattr(self, par, fparams[par]) self.name = self.writename if subblock: if self.prefix != None: if self.prefix != '': self.name = self.prefix + self.name self.dependmask = '' self.tasksdependmask = ''
def createShapes(shape, fRange, rotoNode, rptsw_shapeList, task2, fxsExport, bakeshapes): #=*=*=*=*=*=*==task=related=code======================================== task = nuke.ProgressTask('Shape Exporter') task.setMessage('Creating Shape: %s' % shape[0].name) #=*=*=*=*=*=*=========================================================== #=========================================================================== # CHECK FOR 1 POINT SHAPE AND IGNORE IT, Silhouette doesn't like this #=========================================================================== if len(shape[0]) <= 1: return curvetype = "" shapeRawInfo = shape[0].serialise() shapeRawInfo = shapeRawInfo.split('\n') if [ True for string in ["{curvegroup ", "{cubiccurve "] if shapeRawInfo[0].count(string) > 0 ]: curve = shapeRawInfo[0].split() curvetype = curve[3] shapetype = "Bezier" if curvetype == "bezier" else "Bspline" #=========================================================================== # get shape flags / cubic curve flags #=========================================================================== try: #======================================================================= # not sure what happens here, perhaps a bug on Nuke Roto serialization # sometimes if layers or shapes are selected on the UI the serialization fails # added the error handling below to warn users #======================================================================= shapeFlags = int(shapeRawInfo[0].split()[2]) except: if nuke.GUI: nuke.delete(rotoNode) #clean up cloned node nuke.message( 'ERROR! Aborting Script.\nDeselect any curves/layers on the node before running it again.' ) shapeFlags = parseShapeFlags(shapeFlags) ccshapeFlags = shapeRawInfo[2] ccshapeFlags = int(ccshapeFlags[1:-1].split()[1]) ccshapeFlags = parseShapeFlags(ccshapeFlags) #=========================================================================== global cancel rotoCurve = rotoNode['curves'] rotoRoot = rotoCurve.rootLayer transf = shape[0].getTransform() allAttributes = shape[0].getAttributes() #=========================================================================== # visibility #=========================================================================== hidden = "True" if allAttributes.getValue(0, 'vis') == 0 else "False" locked = "True" if "eLockedFlag" in shapeFlags else "False" #=========================================================================== # visibility end #=========================================================================== #=========================================================================== # Assign shapes to parent layers #=========================================================================== layerlist = fxsExport.findall('Layer') layermatch = False for layer in layerlist: if layer.get('label') == shape[1].name: layermatch = True obj = layer.findall("Properties/Property") for item in obj: if item.get('id') == "objects": fxsShape = ET.SubElement( item, 'Object', { 'type': 'Shape', 'label': shape[0].name, 'shape_type': shapetype, 'hidden': hidden, 'locked': locked }) break if not layermatch: layerlist = fxsExport.findall('.//Object') for layer in layerlist: if layer.get('label') == shape[1].name: obj = layer.findall("Properties/Property") for item in obj: if item.get('id') == "objects": fxsShape = ET.SubElement( item, 'Object', { 'type': 'Shape', 'label': shape[0].name, 'shape_type': shapetype, 'hidden': hidden, 'locked': locked }) break fxsProperties = ET.SubElement(fxsShape, 'Properties') #=========================================================================== # opacity export #=========================================================================== for n in range(0, len(allAttributes)): if allAttributes.getName(n) == "opc": opcindex = n break if allAttributes.getCurve('opc').getNumberOfKeys() > 0: fxsOpacity = ET.SubElement(fxsProperties, 'Property', {'id': 'opacity'}) for key in range(0, allAttributes.getCurve('opc').getNumberOfKeys()): #=================================================================== # interpolation 257 = HOLD #=================================================================== keyinterpolation = allAttributes.getCurve('opc').getKey( key).interpolationType keyinterpolation = "hold" if keyinterpolation == 257 else "linear" fxsOpcKey = ET.SubElement( fxsOpacity, 'Key', { 'frame': str( allAttributes.getKeyTime(opcindex, key) - nuke.root().firstFrame()), 'interp': keyinterpolation }) fxsOpcKey.text = str( allAttributes.getValue(allAttributes.getKeyTime(opcindex, key), 'opc') * 100) else: fxsOpacity = ET.SubElement(fxsProperties, 'Property', { 'constant': 'True', 'id': 'opacity' }) fxsOpacityValue = ET.SubElement(fxsOpacity, 'Value') fxsOpacityValue.text = str( allAttributes.getValue(allAttributes.getKeyTime(opcindex, 0), 'opc') * 100) #=========================================================================== # end of opacity #=========================================================================== #=========================================================================== # shape motion blur start #=========================================================================== fxsMblur = ET.SubElement(fxsProperties, 'Property', { 'constant': 'True', 'id': 'motionBlur' }) fxsMblurValue = ET.SubElement(fxsMblur, 'Value') fxsMblurValue.text = "false" if allAttributes.getValue( 0, 'mbo') == 0 else "true" #=========================================================================== # shape motion blur end #=========================================================================== #=========================================================================== # shape overlay color #=========================================================================== fxsOutlineColor = ET.SubElement(fxsProperties, 'Property', { 'constant': 'True', 'id': 'outlineColor' }) fxsOutlineColorValue = ET.SubElement(fxsOutlineColor, 'Value') r = allAttributes.getValue(0, 'ro') g = allAttributes.getValue(0, 'go') b = allAttributes.getValue(0, 'bo') if r == 0.0 and g == 0.0 and b == 0.0: #if default Nuke "black/none" color, change it to red fxsOutlineColorValue.text = "(1.0,0.0,0.0)" else: fxsOutlineColorValue.text = "(" + str(r) + "," + str(g) + "," + str( b) + ")" #=========================================================================== # shape overlay color end #=========================================================================== #=========================================================================== # shape blending mode #=========================================================================== fxsBlendingMode = ET.SubElement(fxsProperties, 'Property', { 'constant': 'True', 'id': 'mode' }) fxsBlendingModeValue = ET.SubElement(fxsBlendingMode, 'Value') modes = {0: "Add", 12: "Subtract", 13: "Difference", 4: "Max", 5: "Inside"} if modes.get(allAttributes.getValue(0, 'bm')) != None: fxsBlendingModeValue.text = modes.get(allAttributes.getValue(0, 'bm')) else: fxsBlendingModeValue.text = "Add" #=========================================================================== # shape blending mode end #=========================================================================== #=========================================================================== # shape inverted #=========================================================================== fxsInvert = ET.SubElement(fxsProperties, 'Property', { 'constant': 'True', 'id': 'invert' }) fxsInvertedValue = ET.SubElement(fxsInvert, 'Value') if allAttributes.getValue(0, 'inv') == 1: fxsInvertedValue.text = "true" else: fxsInvertedValue.text = "false" #=========================================================================== # shape inverted end #=========================================================================== fxsPath = ET.SubElement(fxsProperties, 'Property', {'id': 'path'}) pathclosed = False if "eOpenFlag" in ccshapeFlags else True #=========================================================================== # check if all the point elements (center and tangents) share linear/hold keyframes and store them for further optimization #=========================================================================== n = 0 keyframeTimes = {} for point in shape[0]: pts = [ point.center.getPositionAnimCurve(0), point.center.getPositionAnimCurve(1), point.leftTangent.getPositionAnimCurve(0), point.leftTangent.getPositionAnimCurve(1), point.rightTangent.getPositionAnimCurve(0), point.rightTangent.getPositionAnimCurve(1) ] curvenames = ["cx", "cy", "ltx", "lty", "rtx", "rty"] for ptype in range(len(pts)): keys = pts[ptype].getNumberOfKeys() for key in range(keys): #=============================================================== # check if current key is in the dict and abort if is already invalid. #=============================================================== if pts[ptype].getKey(key).time not in keyframeTimes: keyframeTimes[pts[ptype].getKey(key).time] = True else: if keyframeTimes.get(pts[ptype].getKey(key).time): acceptKeyframe = False if key > 0: if pts[ptype].getKey( key - 1).rslope == pts[ptype].getKey(key).lslope: acceptKeyframe = True if pts[ptype].getKey(key).interpolationType in [ "257", "258" ]: acceptKeyframe = True elif key == 0: if pts[ptype].getKey( key).rslope == pts[ptype].getKey( key + 1).lslope and pts[ptype].getKey( key).interpolationType in [ 256, 257, 258 ]: acceptKeyframe = True elif keys == 1: acceptKeyframe = True if not acceptKeyframe: keyframeTimes[pts[ptype].getKey(key).time] = False n += 1 keys = sorted(keyframeTimes.items(), key=lambda x: x[0]) #=========================================================================== # removes unwanted keyframes before fRange start, avoiding errors on the subsequent code #=========================================================================== for key in range(len(keys))[::-1]: if keys[key][0] < int(fRange.first()): keys.pop(key) if len(keys) == 0: #safeguard for shapes that have no keyframes at all keys.append([fRange.first(), True]) #=========================================================================== # Creates the keyframes for the curve points # skipping baked frames for linear/hold keyframes that silhouette can handle # all the other interpolation types are baked #=========================================================================== n = 0 for f in fRange: if not keys[n][1] and f <= keys[n][0] or keys[n][1] and f == keys[n][ 0] or f in [fRange.first(), fRange.last()]: fxsPathKey = ET.SubElement( fxsPath, 'Key', { 'frame': str(f - nuke.root().firstFrame()), 'interp': 'linear' }) fxsPathKeyPath = ET.SubElement(fxsPathKey, 'Path', { 'closed': str(pathclosed), 'type': shapetype }) taskCount = 0 for point in shape[0]: #=*=*=*=*=*=*==task=related=code======================================== task.setMessage('Working ' + shape[0].name + ' point ' + str(taskCount + 1) + " of " + str(len(shape[0]))) taskCount += 1 task.setProgress(int(taskCount / len(shape[0]) * 100)) if task.isCancelled(): cancel = True break if cancel: break #=*=*=*=*=*=*==task=related=code======================================== point_c = [ point.center.getPositionAnimCurve(0).evaluate(f), point.center.getPositionAnimCurve(1).evaluate(f) ] point_lt = [ point.center.getPositionAnimCurve(0).evaluate(f) + (point.leftTangent.getPositionAnimCurve(0).evaluate(f) * -1), point.center.getPositionAnimCurve(1).evaluate(f) + (point.leftTangent.getPositionAnimCurve(1).evaluate(f) * -1) ] point_rt = [ point.center.getPositionAnimCurve(0).evaluate(f) + (point.rightTangent.getPositionAnimCurve(0).evaluate(f) * -1), point.center.getPositionAnimCurve(1).evaluate(f) + (point.rightTangent.getPositionAnimCurve(1).evaluate(f) * -1) ] transf = shape[0].getTransform() if bakeshapes: #bake the point position based on shape/parent layers transforms point_c = rptsw_TransformToMatrix(point_c, transf, f) point_c = rptsw_TransformLayers(point_c, shape[1], f, rotoRoot, rptsw_shapeList) point_lt = rptsw_TransformToMatrix(point_lt, transf, f) point_lt = rptsw_TransformLayers(point_lt, shape[1], f, rotoRoot, rptsw_shapeList) point_rt = rptsw_TransformToMatrix(point_rt, transf, f) point_rt = rptsw_TransformLayers(point_rt, shape[1], f, rotoRoot, rptsw_shapeList) x = point_c[0] y = point_c[1] ltx = point_lt[0] rtx = point_rt[0] lty = point_lt[1] rty = point_rt[1] x = worldToImageTransform(x, rotoNode, "x") y = worldToImageTransform(y, rotoNode, "y") ltx = worldToImageTransform(ltx, rotoNode, "x") lty = worldToImageTransform(lty, rotoNode, "y") rtx = worldToImageTransform(rtx, rotoNode, "x") rty = worldToImageTransform(rty, rotoNode, "y") fxsPoint = ET.SubElement(fxsPathKeyPath, 'Point') #"",text = "tst") if shapetype == "Bspline": fxsPoint.text = "(%f,%f)" % ( x, y ) #%f otherwise silhouette may reject the imported shapes. else: fxsPoint.text = "(%f,%f),(%f,%f),(%f,%f)" % (x, y, rtx, rty, ltx, lty) if f == keys[n][0] and keys[n][0] != keys[-1][0]: n += 1 #=========================================================================== # remove repeated keyframes optimization #=========================================================================== if cancel: return #=*=*=*=*=*=*==task=related=code======================================== shapePath = fxsShape.findall(".//Path") removelist = [] for n in range(len(shapePath)): #[::-1]: if n > 0 and n < len(shapePath) - 1: totalp = 0 for nn in range(len(shapePath[n])): #=============================================================== # remove float decimal places from the numbers for comparison #=============================================================== roundness = -3 actual = shapePath[n][nn].text[1:-1].split(",") actual[0] = actual[0][:roundness] actual[1] = actual[1][:roundness] prev = shapePath[n - 1][nn].text[1:-1].split(",") prev[0] = prev[0][:roundness] prev[1] = prev[1][:roundness] next = shapePath[n + 1][nn].text[1:-1].split(",") next[0] = next[0][:roundness] next[1] = next[1][:roundness] #=============================================================== # Silhouette stores all the points on the same keyframe # so we can only delete repeated keyframes if all the points match data #=============================================================== #if this keyframe is equal to previous and next one if actual == prev and actual == next: totalp += 1 if totalp == len(shapePath[n]): removelist.append(n) mainpath = fxsShape.findall(".//Property") for prop in mainpath: if prop.attrib.get('id') == "path": keys = prop.findall(".//Key") keysn = len(keys) - 1 for k in keys[::-1]: if keysn in removelist: prop.remove(k) keysn -= 1
def getInputNodes(afnode, parent): if parent is None: print('Node is "None"') return None if VERBOSE == 2: print('Getting inputs of "%s"' % parent.name()) global LastAfNode global InputNumber global InputName inputnodes = [] for i in range(parent.inputs()): node = parent.input(i) if node is None: continue inputnodes.append(node) if afnode is not None: LastAfNode = afnode addnodes = afnode.knob('addnodes').value() if addnodes is not None and addnodes != '': if VERBOSE == 2: print('Adding nodes "%s" to "%s"' % (addnodes, afnode.name())) rexpr = re.compile(addnodes + '$') addnodes = [] addnodes.extend(nuke.allNodes(RenderNodeClassName, nuke.root())) addnodes.extend(nuke.allNodes(AfanasyNodeClassName, nuke.root())) if len(addnodes) > 1: addnodes.sort(None, getNodeName) for node in addnodes: if rexpr.match(node.name()): inputnodes.append(node) nodes = [] for i in range(len(inputnodes)): node = inputnodes[i] if afnode is not None: InputNumber = i + 1 InputName = node.name() if node.Class() == RenderNodeClassName \ or node.Class() == AfanasyNodeClassName \ or node.Class() == DailiesNodeClassName: disableknob = node.knob('disable') if disableknob: if not disableknob.value(): nodes.append(node) else: if VERBOSE == 1: print('Node "%s" is disabled' % node.name()) continue else: if node.inputs() > 0: childs = getInputNodes(None, node) if childs is None: return None if len(childs) > 0: nodes.extend(childs) else: nuke.message( 'Leaf node reached "%s"-"%s" on "%s" input #%d.' % (node.name(), InputName, LastAfNode.name(), InputNumber) ) return None return nodes
def create_daily_v1(self, group_node): """ Create daily. Version 1 of implementation. """ name = "Quickdaily" # now try to see if we are in a normal work file # in that case deduce the name from it curr_filename = nuke.root().name().replace("/", os.path.sep) version = 0 name = "Quickdaily" if self._snapshot_template.validate(curr_filename): fields = self._snapshot_template.get_fields(curr_filename) name = fields.get("name") version = fields.get("version") # calculate the increment fields = self.context.as_template_fields(self._movie_template) if name: fields["name"] = name if version != None: fields["version"] = version fields["iteration"] = 1 # get all files files = self.tank.paths_from_template(self._movie_template, fields, ["iteration"]) # get all iteration numbers iterations = [ self._movie_template.get_fields(f).get("iteration") for f in files ] if len(iterations) == 0: new_iteration = 1 else: new_iteration = max(iterations) + 1 # compute new file path fields["iteration"] = new_iteration mov_path = self._movie_template.apply_fields(fields) # compute shotgun version name sg_version_name = self._version_template.apply_fields(fields) # get inputs message = self._get_comments(sg_version_name) if message is None: # user pressed cancel! return # set metadata self._setup_formatting(group_node, name, new_iteration) # make sure folders exist for mov mov_folder = os.path.dirname(mov_path) self.ensure_folder_exists(mov_folder) # generate temp file for png sequence png_tmp_folder = tempfile.mkdtemp() png_path = os.path.join(png_tmp_folder, "thumb_seq.%s.png" % PNG_THUMB_SEQUENCE_MARKER) # and render! self._render(group_node, mov_path, png_path) # make thumbnails (thumb, filmstrip) = self._produce_thumbnails(png_path) # create sg version data = { "code": sg_version_name, "description": message, "project": self.context.project, "entity": self.context.entity, "sg_task": self.context.task, "created_by": tank.util.get_current_user(self.tank), "user": tank.util.get_current_user(self.tank), "sg_path_to_movie": mov_path, "sg_first_frame": self._get_first_frame(), "sg_last_frame": self._get_last_frame(), "frame_count": (self._get_last_frame() - self._get_first_frame()) + 1, "frame_range": "%d-%d" % (self._get_first_frame(), self._get_last_frame()), "sg_movie_has_slate": True } # thumbnails and filmstrip thumbnails can be added at creation time to save time if thumb: data["image"] = thumb if filmstrip: data["filmstrip_image"] = filmstrip entity = self.shotgun.create("Version", data) self.log_debug("Version created in ShotgunL %s" % entity) # upload the movie to Shotgun if desired if self.get_setting("upload_movie", False): self.log_debug("Uploading movie to Shotgun") self.shotgun.upload("Version", entity["id"], mov_path, "sg_uploaded_movie") # execute post hook for h in self.get_setting("post_hooks", []): self.execute_hook_by_name(h, mov_path=mov_path, version_id=entity["id"], comments=message) # status message! sg_url = "%s/detail/Version/%s" % (self.shotgun.base_url, entity["id"]) nuke.message("Your submission was successfully sent to review.")
def knobChanged(self, knob): print knob.name() if knob.name() == "SET": # print "OK pressed" sticky = nuke.createNode("StickyNote") sticky.knob("label").setValue( self.label.value() ) sticky.knob("note_font_size").setValue(25) sticky.setXpos(233) sticky.setYpos(-1326) if self.label.setValue == "": sticky = nuke.createNode("StickyNote") sticky.knob("label").setValue( 'Changes/ToDo-Liste' ) nuke.root()['project_directory'].setValue(self.proj.value()) nuke.root()['name'].setValue(self.proj.value()+ self.name.value()) nuke.root()['fps'].setValue(self.realFPS.value()*1.0) nuke.root()['format'].setValue(self.format.value()) #ALL Backdrops_Settings if knob.name() == 'BDROP1': bdrop = nuke.createNode('BackdropNode', inpanel = False) bdrop.knob("name").setValue("INPUT") bdrop.knob("label").setValue('INPUT') bdrop.knob("xpos").setValue(-101) bdrop.knob("ypos").setValue(-1324) bdrop.knob("bdwidth").setValue(300) bdrop.knob("bdheight").setValue(220) bdrop.knob("note_font_size").setValue(50) bdrop.knob("tile_color").setValue(0x515151ff) bdrop.knob("note_font").setValue("Verdana Bold") bdropex = nuke.createNode('BackdropNode', inpanel = False) bdropex.knob("name").setValue("OUTPUT") bdropex.knob("label").setValue('OUTPUT') bdropex.knob("xpos").setValue(-101) bdropex.knob("ypos").setValue(2822) bdropex.knob("bdwidth").setValue(300) bdropex.knob("bdheight").setValue(220) bdropex.knob("note_font_size").setValue(50) bdropex.knob("tile_color").setValue(0xe5c634ff) bdropex.knob("note_font").setValue("Verdana Bold") bdropp = nuke.createNode("Dot", inpanel = False) bdropp.knob("xpos").setValue(35) bdropp.knob("ypos").setValue(-1165) bdropp2 = nuke.createNode("Dot", inpanel = False) bdropp2.knob("xpos").setValue(35) bdropp2.knob("ypos").setValue(2919) if knob.name() == 'BDROP2' : bdrop2 = nuke.createNode('BackdropNode', inpanel = False) bdrop2.knob("name").setValue("CG_Passes") bdrop2.knob("label").setValue('CG_Passes') bdrop2.knob("xpos").setValue(-1135) bdrop2.knob("ypos").setValue(-1310) bdrop2.knob("bdwidth").setValue(380) bdrop2.knob("bdheight").setValue(210) bdrop2.knob("note_font_size").setValue(35) bdrop2.knob("tile_color").setValue(0x880200ff) if knob.name() == 'BDROP3' : bdrop3 = nuke.createNode('BackdropNode', inpanel = False) bdrop3.knob("name").setValue("Blacklevels") bdrop3.knob("label").setValue('Blacklevels') bdrop3.knob("xpos").setValue(-107) bdrop3.knob("ypos").setValue(1783) bdrop3.knob("bdwidth").setValue(270) bdrop3.knob("bdheight").setValue(210) bdrop3.knob("note_font_size").setValue(35) bdrop3.knob("tile_color").setValue(0xff) if knob.name() == 'BDROP4' : bdrop4 = nuke.createNode('BackdropNode', inpanel = False) bdrop4.knob("name").setValue("_POST") bdrop4.knob("label").setValue('_POST') bdrop4.knob("xpos").setValue(-100) bdrop4.knob("ypos").setValue(2103) bdrop4.knob("bdwidth").setValue(272) bdrop4.knob("bdheight").setValue(402) bdrop4.knob("note_font_size").setValue(35) bdrop4.knob("tile_color").setValue(0x537cff) if knob.name() == 'BDROP5' : bdrop5 = nuke.createNode('BackdropNode', inpanel = False) bdrop5.knob("name").setValue("Colour_Correction") bdrop5.knob("label").setValue('Colour_Correction') bdrop5.knob("xpos").setValue(585) bdrop5.knob("ypos").setValue(464) bdrop5.knob("bdwidth").setValue(490) bdrop5.knob("bdheight").setValue(256) bdrop5.knob("note_font_size").setValue(35) bdrop5.knob("tile_color").setValue(0xffffffff) if knob.name() == 'BDROP6' : bdrop6 = nuke.createNode('BackdropNode', inpanel = False) bdrop6.knob("name").setValue("Despill") bdrop6.knob("label").setValue('Despill') bdrop6.knob("xpos").setValue(580) bdrop6.knob("ypos").setValue(-162) bdrop6.knob("bdwidth").setValue(777) bdrop6.knob("bdheight").setValue(488) bdrop6.knob("note_font_size").setValue(35) bdrop6.knob("tile_color").setValue(0x264f2aff) if knob.name() == 'BDROP7' : bdrop7 = nuke.createNode('BackdropNode', inpanel = False) bdrop7.knob("name").setValue("Keying") bdrop7.knob("label").setValue('Keying') bdrop7.knob("xpos").setValue(579) bdrop7.knob("ypos").setValue(-1038) bdrop7.knob("bdwidth").setValue(1400) bdrop7.knob("bdheight").setValue(800) bdrop7.knob("note_font_size").setValue(35) bdrop7.knob("tile_color").setValue(0xa045ff) if knob.name() == 'BDROP8' : bdrop8 = nuke.createNode('BackdropNode', inpanel = False) bdrop8.knob("name").setValue("3D_Camera-Projection") bdrop8.knob("label").setValue('3D_Camera-Projection') bdrop8.knob("xpos").setValue(-1487) bdrop8.knob("ypos").setValue(-163) bdrop8.knob("bdwidth").setValue(1060) bdrop8.knob("bdheight").setValue(740) bdrop8.knob("note_font_size").setValue(35) bdrop8.knob("tile_color").setValue(0xa03c3cff) if knob.name() == "DELETE": for w in nuke.allNodes(): w.setSelected(True) nukescripts.node_delete() for k in (self.bdrop1, self.bdrop2, self.bdrop3, self.bdrop4, self.bdrop5, self.bdrop6, self.bdrop7, self.bdrop8 ): k.setValue(False) if knob.name() == "Ordner": ## Define which folders you need RD = nuke.Root()['project_directory'].value() R = 'RENDER' S = 'SCRIPTS' TWDR = 'ASSETS/2D_RENDERS' THDR = 'ASSETS/3D_RENDERS' ST = 'ASSETS/STILLS' F = 'FOOTAGE' ## Combines Folders with Project Directory F1 = RD+R F2 = RD+S F3 = RD+TWDR F4 = RD+THDR F5 = RD+ST F6 = RD+F ## Prints for Debugging print F1 print F2 print F3 print F4 print F5 print F6 ## Generates Folders if not os.path.exists(F1): os.makedirs(F1) if not os.path.exists(F2): os.makedirs(F2) if not os.path.exists(F3): os.makedirs(F3) if not os.path.exists(F4): os.makedirs(F4) if not os.path.exists(F5): os.makedirs(F5) if not os.path.exists(F6): os.makedirs(F6) nuke.message('Folders Generated') if knob.name() == "SAVE": nuke.scriptSave() if knob.name() == "CANCEL": self.finishModalDialog(True) ########second tab: Open new script if knob.name() == "OPEN": nuke.scriptOpen(self.ChooseScript.value()) if knob.name() == "CheckFiles": path = self.Proj_Folder.value() files = [] for r, d, f in os.walk(path): for item in f: if self.filter.value() in item: files.append(os.path.join(r, item)) if '~' in item: files.remove(os.path.join(r,item)) #print files self.ChooseScript.setValues(files) #print len(files) self.listcount.setValue(str(len(files))) if knob.name() == "CANCEL2": self.finishModalDialog(True)
def SequenceLoader(self): '''main function construct the image group''' dir_renderVersion = joinPath(self.lgtPath.text(), self.renderVersion_mu.currentText()) if dir_renderVersion == None: nuke.message("Import Canceled") else: name_renderVersion = os.path.basename( dir_renderVersion.rstrip('/')) # TIO_orbit_1k_v001 ver_renderVersion = int(name_renderVersion.split('_v')[1]) RGBA = 'beauty' # Building Image Group ls_aov = getAOVs(dir_renderVersion) for p in ls_aov[ls_aov.keys()[0]]: nuke.Layer(p, [ '%s.red' % p, '%s.green' % p, '%s.blue' % p, '%s.alpha' % p ]) # nodeLabel = '%s\nv%s' % (name_renderVersion.split('_v')[0], name_renderVersion.split('_v')[1]) nodeLabel = "nuke.thisNode().name()+'\\n'+nuke.thisNode()['tx_version'].value()+'\\n\\n'+nuke.thisNode()['tx_layer'].value()+'\\n'+'v'+nuke.thisNode()['int_thisVersion'].value()" for l in ls_aov.keys(): imgGroup = nuke.nodes.Group(autolabel=nodeLabel, postage_stamp=1) imgGroup.setName('kpRead1') t_tab = nuke.Tab_Knob('tb_user', 'kpRead') k_pipeline = nuke.Text_Knob('kupipeline', 'kpRead', 'kpRead') # Ku Pipeline Identifier k_renderVersion = nuke.Text_Knob( 'tx_version', '<b>render: </b>', name_renderVersion.split('_v')[0]) mod = os.path.basename(__file__).split('.py')[0] k_verUp = nuke.PyScript_Knob( 'btn_verUp', '<b>▲</b>', '%s.versionUp(nuke.thisNode())' % mod) k_verDown = nuke.PyScript_Knob( 'btn_verDown', '<b>▼</b>', '%s.versionDown(nuke.thisNode())' % mod) k_verLatest = nuke.PyScript_Knob( 'btn_verLatest', '<b>★</b>', '%s.versionLatest(nuke.thisNode())' % mod) k_thisVersion = nuke.Text_Knob('int_thisVersion', '<b>version: </b>') k_thisVersion.setValue('%03d' % ver_renderVersion) k_renderLayer = nuke.Text_Knob('tx_layer', '<b>layer: </b>', l) k_div = nuke.Text_Knob('', "<b>Switch Version:</b>") k_path = nuke.Text_Knob('tx_dir', '<b>path: </b>', dir_renderVersion) # k_aov = nuke.Text_Knob('tx_aov', '<b>aovs: </b>', '\n'.join(ls_aov[l])) # k_thisVersion.setEnabled(False) k_thisVersion.setFlag(nuke.STARTLINE) k_path.setVisible(False) k_verUp.setFlag(nuke.STARTLINE) k_verUp.setTooltip("Version Up") k_verDown.clearFlag(nuke.STARTLINE) k_verDown.setTooltip("Version Down") k_verLatest.clearFlag(nuke.STARTLINE) k_verLatest.setTooltip("Latest Version") k_pipeline.setVisible(False) for k in [ t_tab, k_pipeline, k_path, k_renderVersion, k_thisVersion, k_renderLayer, k_div, k_verUp, k_verDown, k_verLatest ]: imgGroup.addKnob(k) with imgGroup: aov_beauty = None aov_rest = [] for p in ls_aov[l]: path = joinPath(dir_renderVersion, l, p) createRead(path) aov_beauty = nuke.toNode(RGBA) aov_rest = [ n for n in nuke.allNodes('Read') if n != aov_beauty ] shuffling(aov_beauty, aov_rest) self.close()
def _archiveThisComp(): import nuke import os import shutil from fnmatch import fnmatch from time import strftime #variable declarations n = nuke.allNodes() destPath = None seqNameEnds = ('%04d', '####') archiverParams = { 'outPath' : ["W:/",]} #---------------------- #-----Doin' Stuff------ #---------------------- panelResult = _archiverPanel(**archiverParams) #If they hit OK if panelResult is 1: #get panel values and build new local path for footage localPath = archiverParams['outPath'][0] #check if local directory already exists. Ask to create it if it doesn't if not os.path.exists(localPath): if nuke.ask("Directory does not exist. Create now?"): os.makedirs(localPath) else: raise Exception, "Not a valid target directory." #get and strip script name scriptName = nuke.Root().name().rpartition('/')[2] #save script to archive path newScriptPath = localPath + scriptName nuke.scriptSaveAs(newScriptPath) #create log file and write header info to it fOut = open(localPath + 'Archive Log.txt', 'w') fOut.write('Comp archived %s at %s\n\n\n' % (strftime("%m/%d/%Y"), strftime("%H:%M:%S"))) fOut.write('Comp Name: %s\n\n' % (scriptName, )) fOut.write('Files archived to:\n\t%s\n\n\n' % (localPath, )) tempCount = 0 #build lists of Read and ReadGeo nodes readNodes = [i for i in n if i.Class() == "Read"] readPaths = [node['file'].value() for node in readNodes] readGeoNodes = [i for i in n if i.Class() == "ReadGeo2" or i.Class() == "ReadGeo"] readGeoPaths = [node['file'].value() for node in readGeoNodes] #REMOVE DUPLICATE READ NODES AND REPLACE THEM WITH POSTAGE STAMPS dupNodes = [] for node in readNodes: dupSet = [] if readPaths.count(node['file'].value()) > 1: dupSet = [i for i in readNodes if i['file'].value() == node['file'].value()] dupNodes.append(dupSet) for dup in dupSet: readNodes.remove(dup) readPaths.remove(dup['file'].value()) if dupNodes: for set in dupNodes: set.sort() readNodes.append(set[0]) for count in range(1,len(set)): set[count]['selected'].setValue(True) pStamp = nuke.nodes.PostageStamp(name = "PStamp_" + set[count].name(), label = set[count].name(), hide_input = True, xpos = set[count].xpos(), ypos = set[count].ypos()) pStamp.setInput(0,set[0]) nuke.delete(set[count]) #process Read nodes fOut.write('Read nodes and associated source files:\n') for node in readNodes: tempCount += 1 #get Read node's footage path netPath = node['file'].value() netPathTuple = netPath.rpartition('/') #build local path to assign to Read node localReadPath = '%sfootage/%s' % (localPath, node.name()) #create local folder for current Read node os.makedirs(localReadPath) seqName = netPathTuple[2] seqTuple = seqName.rpartition('.') #test whether the Read node is reading a sequence or a single file and proceed accordingly if seqTuple[0].endswith(seqNameEnds): tempCount += 1 seqPrefixTuple = seqTuple[0].partition(seqTuple[0][-4]) print "\n\nCopying sequence %d: %s..." % (tempCount, seqName) for fileName in os.listdir(netPathTuple[0]): if fnmatch(fileName, seqPrefixTuple[0] + '*'): shutil.copy2('%s/%s' % (netPathTuple[0], fileName), localReadPath) #single file copy script else: print "\n\nCopying plate: %s..." % (netPath.rpartition('/')[2], ) try: shutil.copy2(netPath, localReadPath) except WindowsError: print "...Plate already exists" #re-path each Read node to the local footage node['file'].setValue('%sfootage/%s/%s' % (localPath, node.name(), seqName)) #write string containing Read node name followed by file sequence to output file fOut.write('\t%s: %s\n' % (node.name(), seqName)) #process Geometry nodes localReadGeoPath = "" if readGeoNodes: fOut.write('\nReadGeo nodes and associated geometry files:\n') #create local folder for geometry files localReadGeoPath = localPath + 'geometry/' os.makedirs(localReadGeoPath) print "Copying geometry..." for node in readGeoNodes: #get ReadGeo node's file path netPath = node['file'].value() netPathTuple = netPath.rpartition('/') #single file copy script shutil.copy2(netPath, localReadGeoPath) #re-path each ReadGeo node to the local file node['file'].setValue('%sgeometry/%s' % (localPath, netPathTuple[2])) #write string containing ReadGeo node name followed by geometry file name to output file fOut.write('\t%s: %s\n' % (node.name(), netPathTuple[2])) print "Done" #write total number of copied files to output file fOut.write('\n\n%d files total' % (sum((len(f) for _, _, f in os.walk(localPath)))-2, )) fOut.close() #save script nuke.scriptSave() nuke.message("Archive complete") #CANCEL else: nuke.message("Canceled by user")
def genBlock(self, i_scene_path): if VERBOSE == 2: print('Generating block "%s"' % self.name) if not self.valid: return if self.wnode.Class() == RenderNodeClassName: block = af.Block(self.name, AfanasyServiceType) block.setNumeric(self.framefirst, self.framelast, self.framespertask, self.frameinc) block.setFiles(self.imgfiles) if self.skipexisting: block.skipExistingFiles() if self.framesequential != 1: block.setSequential( self.framesequential) if self.capacity != -1: block.setCapacity(self.capacity) if self.maxruntime != -1: block.setTasksMaxRunTime(self.maxruntime) if self.tickets_use and self.tickets_data is not None and len(self.tickets_data): for ticket in self.tickets_data.split(','): ticket = ticket.strip().split(':') if len(ticket) != 2: nuke.message('Invalid ticket data: "%s".' % ticket) continue block.addTicket(ticket[0], int(ticket[1])) cmd = os.getenv('NUKE_AF_RENDER', 'nuke') if self.tmpimage or self.pathsmap: cgru_location = os.getenv('CGRU_LOCATION') if cgru_location is None: print( 'CGRU_LOCATION is not set, can`t enable tmpimage ' 'and pathsmap' ) else: # That the Nuke-Render-Script need to # rewrite the Script and replace file to render in # temporary image file nukerenderscript = os.environ['CGRU_LOCATION'] nukerenderscript = os.path.join(nukerenderscript, 'plugins') nukerenderscript = os.path.join(nukerenderscript, 'nuke') nukerenderscript = os.path.join(nukerenderscript, 'render.py') cmd += ' -t %s' % nukerenderscript if not self.tmpimage: cmd += ' --notmpimage' if not self.pathsmap: cmd += ' --nopathsmap' cmd += ' -X %s -F@#@-@#@x%d -x \"%s\"' % \ (self.writename, self.frameinc, i_scene_path) block.setCommand(cmd) elif self.wnode.Class() == DailiesNodeClassName: cgru = __import__('cgru', globals(), locals(), []) cgru.dailiesEvaluate(self.wnode) cmd = cgru.dailiesGenCmd(self.wnode) if cmd is None or cmd == '': return block = af.Block( os.path.basename(cmd.split(' ')[-1]), DailiesServiceType ) if self.capacity != -1: block.setCapacity(self.capacity) task = af.Task('dailies') task.setCommand(cmd) block.tasks.append(task) else: print('Invalid block node class = "%s"' % self.wnode.Class()) return if self.dependmask != '': block.setDependMask(self.dependmask) if self.tasksdependmask != '': block.setTasksDependMask(self.tasksdependmask) if self.subblock: if self.maxruntasks != -1: block.setMaxRunningTasks(self.maxruntasks) if self.maxperhost != -1: block.setMaxRunTasksPerHost(self.maxperhost) if self.hostsmask is not None: self.hostsmask = str(self.hostsmask) if self.hostsmask != '': block.setHostsMask(self.hostsmask) if self.hostsmaskexclude is not None: self.hostsmaskexclude = str(self.hostsmaskexclude) if self.hostsmaskexclude != '': block.setHostsMaskExclude(self.hostsmaskexclude) return block
def print_keys(): n = nuke.thisNode() k = nuke.thisKnob() name = k.label() #print knob try: array_size = len(n[knob].value()) except: array_size = 1 print array_size if array_size == 4: animCurveX = k.animation(0) #ANIMATION IN THE FIRST FIELD (X VALUE) animCurveY = k.animation(1) #ANIMATION IN THE SECOND FIELD (Y VALUE) animCurveZ = k.animation(2) #ANIMATION IN THE SECOND FIELD (Z VALUE) animCurveW = k.animation(3) #ANIMATION IN THE SECOND FIELD (W VALUE) for key in animCurveX.keys(): xValueX = key.x yValueX = key.y print '%s X at %s has value %s' % (name, xValueX, yValueX) print "-------------------------" for key in animCurveY.keys(): xValueY = key.x yValueY = key.y print '%s Y at %s has value %s' % (name, xValueY, yValueY) print "-------------------------" for key in animCurveZ.keys(): xValueZ = key.x yValueZ = key.y print '%s Z at %s has value %s' % (name, xValueZ, yValueZ) print "-------------------------" for key in animCurveW.keys(): xValueW = key.x yValueW = key.y print '%s Z at %s has value %s' % (name, xValueW, yValueW) print "-------------------------" if array_size == 3: animCurveX = k.animation(0) #ANIMATION IN THE FIRST FIELD (X VALUE) animCurveY = k.animation(1) #ANIMATION IN THE SECOND FIELD (Y VALUE) animCurveZ = k.animation(2) #ANIMATION IN THE SECOND FIELD (Z VALUE) for key in animCurveX.keys(): xValueX = key.x yValueX = key.y print '%s X at %s has value %s' % (name, xValueX, yValueX) print "-------------------------" for key in animCurveY.keys(): xValueY = key.x yValueY = key.y print '%s Y at %s has value %s' % (name, xValueY, yValueY) print "-------------------------" for key in animCurveZ.keys(): xValueZ = key.x yValueZ = key.y print '%s Z at %s has value %s' % (name, xValueZ, yValueZ) print "-------------------------" if array_size == 2: animCurveX = k.animation(0) #ANIMATION IN THE FIRST FIELD (X VALUE) animCurveY = k.animation(1) #ANIMATION IN THE SECOND FIELD (Y VALUE) for key in animCurveX.keys(): xValueX = key.x yValueX = key.y print '%s X at %s has value %s' % (name, xValueX, yValueX) print "-------------------------" for key in animCurveY.keys(): xValueY = key.x yValueY = key.y print '%s Y at %s has value %s' % (name, xValueY, yValueY) print "-------------------------" if array_size == 1: animCurveX = k.animation(0) #ANIMATION IN THE FIRST FIELD (X VALUE) l = [] for key in animCurveX.keys(): xValueX = key.x yValueX = key.y x = '%s X at %s has value %s' % (name, xValueX, yValueX) l.append(x) o = "" for one in l: o = o + one + "\n" nuke.message(o)
def autoCrop_MB(): #Check if a node is selected. try: n = nuke.selectedNode() nodeClass = n.Class() except: n = 0 #Run if statement based on above try statement. if n == 0: print nuke.message('Please selected a node to run autoCrop_MB on...') else: #Check how many nodes are selected. numberOfNodes = len(nuke.selectedNodes()) #Convert the int to a str. numberOfNodesInt = str(numberOfNodes) #Get channels from stream and sort so alpha is at the top. channelL = n.channels() channelS = channelL.sort() #Convert list to a string and add space. channelS = ' '.join(channelL) if nodeClass == 'Read': range = 'input' + ' ' + 'global' + ' ' + 'custom' else: range = 'global' + ' ' + 'custom' #Create and execute panel. p = nuke.Panel('autoCrop_MB v3.5') p.addEnumerationPulldown('frame range', range) p.addSingleLineInput('custom start', '') p.addSingleLineInput('custom end', '') p.addEnumerationPulldown('layer', channelS) p.addBooleanCheckBox('crop to format', False) p.show() increment = int('1') layersForCrop = p.value('layer') #Add quotation marks to layers variables. layersToAnalysis = '\"' + layersForCrop + '\"' #Work out the frame range wanted. if p.value('frame range') == 'custom': startFrame = int(p.value('custom start')) endFrame = int(p.value('custom end')) else: if p.value('frame range') == 'input': startFrame = n.knob('first').getValue() endFrame = n.knob('last').getValue() else: root = nuke.root() startFrame = int(root.knob("first_frame").value()) endFrame = int(root.knob("last_frame").value()) #Reset variables. first = startFrame last = endFrame inc = increment layer = layersToAnalysis #Run autocrop in curve tool. Taken from The Foundry's nukescripts/crop.py # Remember original set of selected nodes...we'll need this original_nodes = nuke.selectedNodes() # Deselect everything so we can add CurveTool nodes all_nodes = nuke.allNodes() for i in all_nodes: i.knob("selected").setValue(False) for i in original_nodes: # Reselect originally selected nodes and create a CurveTool node, # which will automatically connect to the last selected. i.knob("selected").setValue(True) #Check if user wants to analysis outside the format. if p.value('crop to format') == True: autocropper = nuke.createNode( "CurveTool", '''operation 0 ROI {0 0 input.width input.height} Layer %s label "Processing Crop..." selected true''' % (str(layer), ), False) else: autocropper = nuke.createNode( "CurveTool", '''operation 0 ROI {input.bbox.x input.bbox.y input.bbox.r input.bbox.t} Layer %s label "Processing Crop..." selected true''' % (str(layer), ), False) # Execute the CurveTool node thru all the frames nuke.executeMultiple([ autocropper, ], ([first, last, inc], )) # select the curvewriter autocropper.knob("selected").setValue(True) # add crop node cropnode = nuke.createNode("Crop", "label AutoCrop", False) # put the new data from the autocrop into the new crop cropbox = cropnode.knob("box") autocropbox = autocropper.knob("autocropdata") cropbox.copyAnimations(autocropbox.animations()) # turn on the animated flag cropnode.knob("indicators").setValue(1) # deselect everything all_nodes = nuke.allNodes() for j in all_nodes: j.knob("selected").setValue(False) # select the curvewriter and delete it autocropper.knob("selected").setValue(True) # delete the autocropper to make it all clean #nodes.node_delete() nuke.delete(autocropper) # deselect everything all_nodes = nuke.allNodes() for j in all_nodes: j.knob("selected").setValue(False) # select the new crop cropnode.knob("selected").setValue(True) # place it in a nice spot nuke.autoplace(cropnode) # De-Select it cropnode.knob("selected").setValue(False)
def Bulk_Samples_Conversion(self,oldfilepath,newfilepath): #print oldfilepath #print newfilepath j=1 #print self.myContactReadDict for mykey in self.myContactReadDict.keys(): for myRead in self.myContactReadDict[mykey]: self.myReads.remove(myRead) readPath=myRead['file'].value() filePath = readPath.replace(oldfilepath, newfilepath) #print filePath readDir=os.path.split(filePath)[0] if not os.path.isdir(readDir): self.warning.append(myRead.name()) continue Flag=True myRead['file'].setValue(filePath) formatW=myRead.width() formatH = myRead.height() #print formatH ReadOFormat = myRead['format'].value() #print ReadOFormat.width() if ReadOFormat.width() != formatW or ReadOFormat.height() != formatH: allFormat = nuke.formats() if self.myOrangeDict: for myOrange in self.myOrangeDict.keys(): SazeW = self.myOrangeDict[myOrange].split(" ")[0] SazeH = self.myOrangeDict[myOrange].split(" ")[1] if SazeW == formatW and SazeH == formatH: myRead['format'].setValue(myOrange) Flag = False break if Flag: for eachFormat in allFormat: if eachFormat.width() == formatW and eachFormat.height() == formatH: #print eachFormat.width() #print formatW myFormat = eachFormat.name() print myFormat if myFormat != None: #print "sssss" myRead['format'].setValue(myFormat) Flag = False break if Flag: #键的名字 while True: mySize = ('my_Size%s' % j) #print mySize if mySize not in [eachFormat.name() for eachFormat in allFormat]: break else: j += 1 #print j widthHeight = str(formatW) + " " + str(formatH) self.myOrangeDict.update({mySize:widthHeight}) square = widthHeight+" "+mySize nuke.addFormat(square) myRead['format'].setValue(mySize) frameOrange=pyseq.getSequences(readDir) for frames in frameOrange: myPath = frames.path() if os.path.isdir(myPath): continue else: if frames.tail(): if frames.length()==1: myRead['origfirst'].setValue(1) myRead['origlast'].setValue(1) myRead['first'].setValue(1) myRead['last'].setValue(1) else: firstFrameName = frames[0]._get_filename() lastFrameName = frames[-1]._get_filename() readFileStart=firstFrameName.split(".")[-2] readFileLast=lastFrameName.split(".")[-2] myRead['origfirst'].setValue(int(readFileStart)) myRead['origlast'].setValue(int(readFileLast)) myRead['first'].setValue(int(readFileStart)) myRead['last'].setValue(int(readFileLast)) _w=self.myContactReadDict[mykey][0].knob('format').value().width() _h=self.myContactReadDict[mykey][0].knob('format').value().height() #print _w #print _h constRows=mykey['rows'].value() constColumns=mykey['columns'].value() #print constRows #print constColumns mykey['height'].setValue(constRows*_h) mykey['width'].setValue(constColumns*_w) if self.myReads: for myRead in self.myReads: readPath=myRead['file'].value() filePath = readPath.replace(oldfilepath, newfilepath) Flag=True readDir=os.path.split(filePath)[0] if not os.path.isdir(readDir): self.warning.append(myRead.name()) continue myRead['file'].setValue(filePath) formatW=myRead.width() formatH = myRead.height() #print formatH ReadOFormat = myRead['format'].value() if ReadOFormat.width() != formatW or ReadOFormat.height() != formatH: allFormat = nuke.formats() if self.myOrangeDict: for myOrange in self.myOrangeDict.keys(): SazeW = self.myOrangeDict[myOrange].split(" ")[0] SazeH = self.myOrangeDict[myOrange].split(" ")[1] if SazeW == formatW and SazeH == formatH: myRead['format'].setValue(myOrange) Flag = False break if Flag: for eachFormat in allFormat: if eachFormat.width() == formatW and eachFormat.height() == formatH: myFormat = eachFormat.name() if myFormat != None: myRead['format'].setValue(myFormat) Flag = False break if Flag: #键的名字 while True: mySize = ('my_Size%s' % j) if mySize not in [eachFormat.name() for eachFormat in allFormat]: break else: j += 1 widthHeight = str(formatW) + " " + str(formatH) self.myOrangeDict.update({mySize:widthHeight}) square = widthHeight+" "+mySize nuke.addFormat(square) myRead['format'].setValue(mySize) frameOrange=pyseq.getSequences(readDir) for frames in frameOrange: myPath = frames.path() if os.path.isdir(myPath): continue else: if frames.tail(): if frames.length()==1: myRead['origfirst'].setValue(1) myRead['origlast'].setValue(1) myRead['first'].setValue(1) myRead['last'].setValue(1) else: firstFrameName = frames[0]._get_filename() lastFrameName = frames[-1]._get_filename() readFileStart=firstFrameName.split(".")[-2] readFileLast=lastFrameName.split(".")[-2] myRead['origfirst'].setValue(int(readFileStart)) myRead['origlast'].setValue(int(readFileLast)) myRead['first'].setValue(int(readFileStart)) myRead['last'].setValue(int(readFileLast)) if self.warning: nuke.message(str(self.warning)+"\xe8\x8a\x82\xe7\x82\xb9\xe6\x96\xb0\xe8\xb7\xaf\xe5\x8a\xb2\xe4\xb8\x8d\xe5\xad\x98\xe5\x9c\xa8")
def missingFrames(): missingFiles = [] completeFileName = "" # first check if a node is selected and if so if it is a read node selectedNodes = nuke.selectedNodes() # either nothing or too much is selected if (len(selectedNodes) != 1): nuke.message("This only works if you select one Read node!") return "Fail" nodeType = selectedNodes[0].Class() if (nodeType != "Read"): nuke.message("This only works if you select one Read node!") return "Fail" #now we are sure one read node is selected, so go on. readNode = selectedNodes[0] fileNameLong = readNode.knob("file").value() startFrame = readNode.knob("first").value() endFrame = readNode.knob("last").value() # split the long file name with path to its subsections splitFileNameLong = os.path.split(fileNameLong) fileNameShort = splitFileNameLong[1] pathName = splitFileNameLong[0] splitFileName = fileNameShort.split(".") if (len(splitFileName) != 3): nuke.message( "File does not have the format name.number.ext.\nSearch the missing frames yourself :)" ) return "Fail" fileName = splitFileName[0] filePaddingOrg = splitFileName[1] filePaddingLength = len((filePaddingOrg) % 0) fileExtension = splitFileName[2] # now with all that given information search for missing files in the sequence for i in range(startFrame, endFrame + 1): # first build the string of the padded frameNumbers frameNumber = str(i) while (len(frameNumber) < filePaddingLength): frameNumber = "0" + frameNumber completeFileName = pathName + "/" + fileName + "." + frameNumber + "." + fileExtension if not os.path.isfile(completeFileName): missingFiles.append(i) if (len(missingFiles) == 0): nuke.message("No file seems to be missing") return cleanedUpMissingFiles = cleanUpList(missingFiles) nuke.message("In the frame range: " + str(startFrame) + "-" + str(endFrame) + "\nThe following files are missing:\n\n" + cleanedUpMissingFiles) return
def validate(self, exportItems): if self.session == -1: nuke.message("Please login to kitsu.") return False elif self.session == -2: nuke.message( "Your kitsu account does not have the permission to create shots." ) return False elif self.session: if self.projectsC.currentRow() > 0: self.preset().properties( )["kitsuProjectID"] = self.projectsC.currentItem().data( Qt.UserRole) self.preset().properties( )["kitsuTaskTypeName"] = self.tasksC.currentText() self.preset().properties( )["kitsuTaskStatusName"] = self.statusC.currentText() foundKitsuPrev = False for (exportPath, preset) in self._exportTemplate.flatten(): if "kitsuProjectID" in preset.properties(): foundKitsuPrev = True if preset.properties()["file_type"] != "mov": nuke.message( "kitsu uploader current only supports mov file type. " ) return False if foundKitsuPrev: return ShotProcessorUI.validate(self, exportItems) else: nuke.message( "Did not find a KitsuPreviewExporter in the export structure." ) return False else: nuke.message("Please select a kitsu project.") return False else: nuke.message("Unknown kitsu error.") return False
def cmd(m=message): nuke.message(m)
def dailiesGenCmd(node): # Process Input Node: inputnode = None for i in range(node.inputs()): inputnode = node.input(i) if inputnode is None: nuke.message( 'Error:\n' '%s\n' 'Not connected to Read or Write node.' % node.name() ) return if not inputnode.Class() in ['Read', 'Write']: nuke.message( 'Error:\n' '%s\n' 'Connected not to Read or Write node.' % node.name() ) return # Process Images: images = '' root_frame_first = nuke.Root().firstFrame() root_frame_last = nuke.Root().lastFrame() if root_frame_first == root_frame_last: root_frame_last += 100 # Get needed views from dailies node if forced: if node.knob('forceviews').value(): views = node.knob('viewsnames').value().split(' ') else: # Get needed views write node: views_knob = inputnode.knob('views') if views_knob is not None: views = inputnode.knob('views').value().split(' ') else: # Get all scene views: views = nuke.views() # Generate input pattern from each view: for view in views: if not len(view): continue # skip empty view, may be after split(' ') if not view in nuke.views(): print('Error: Skipping invalid view: "%s"' % view) continue octx = nuke.OutputContext() octx.setView(1 + nuke.views().index(view)) octx.setFrame(root_frame_first) images1 = inputnode.knob('file').getEvaluatedValue(octx) if images1 is None or images1 == '': nuke.message( 'Error:\n' '%s\n' 'Files are empty.\n' 'View "%s", frame %d.' % (inputnode.name(), view, root_frame_first) ) return octx.setFrame(root_frame_last) images2 = inputnode.knob('file').getEvaluatedValue(octx) if images2 is None or images2 == '': nuke.message( 'Error:\n' '%s\n' 'Files are empty.\n' 'View "%s", frame %d.' % (inputnode.name(), view, root_frame_last) ) return part1, padding, part2 = afcommon.splitPathsDifference(images1, images2) if padding < 1: nuke.message( 'Error:\n' '%s\Invalid files pattern.\n' 'View "%s".' % (inputnode.name(), view) ) return if len(images): images += ' ' images += '%s%s%s' % (part1, '#' * padding, part2) if images == '': nuke.message('Error:\n%s\nNo valid views found.' % inputnode.name()) return # Get Movie Name: movname = node.knob('movname').value() if movname is None or movname == '': nuke.message('Error:\n%s\nMovie name is not set.' % node.name()) return # Get Movie Folder: movfolder = node.knob('movfolder').getEvaluatedValue() if movfolder is None or movfolder == '': nuke.message('Error:\n%s\nMovie folder is not set.' % node.name()) return # Get Parameters: format = node.knob('format').value() fps = node.knob('fps').value() codec = node.knob('codec').value() template = node.knob('template').getEvaluatedValue() slate = node.knob('slate').getEvaluatedValue() company = node.knob('company').value() project = node.knob('project').value() shot = node.knob('shot').value() version = node.knob('version').value() artist = node.knob('artist').value() activity = node.knob('activity').value() comments = node.knob('comments').value() cach_op = node.knob('cach_op').value() line_clr = node.knob('line_clr').value() draw169 = node.knob('draw169').value() draw235 = node.knob('draw235').value() line169 = node.knob('line169').value() line235 = node.knob('line235').value() lgspath = node.knob('lgspath').getEvaluatedValue() lgfpath = node.knob('lgfpath').getEvaluatedValue() lgsgrav = node.knob('lgsgrav').value() lgfgrav = node.knob('lgfgrav').value() lgssize = int(node.knob('lgssize').value()) lgfsize = int(node.knob('lgfsize').value()) fstart = int(node.knob('fstart').value()) fend = int(node.knob('fend').value()) fffirst = int(node.knob('fffirst').value()) faketime_on = int(node.knob('faketime_on').value()) faketime_str = node.knob('faketime_str').value() encodeonly = node.knob('encodeonly').value() tmpformat = node.knob('tmpformat').value() tmpquality = node.knob('tmpquality').value() autocolorspace = int(node.knob('autocolorspace').value()) asp_in = float(node.knob('asp_in').value()) gamma = float(node.knob('gamma').value()) cach_as = float(node.knob('cach_as').value()) line_as = float(node.knob('line_as').value()) # Command Construction: cmd = os.environ['CGRU_LOCATION'] cmd = os.path.join(cmd, 'utilities') cmd = os.path.join(cmd, 'moviemaker') cmd = os.path.join(cmd, 'makemovie.py') cmd = 'python ' + cmd cmd += ' -f "%s"' % fps cmd += ' -c "%s"' % codec if faketime_on and faketime_str is not None and faketime_str != '': cmd += ' --faketime %d' % \ int(time.mktime(time.strptime(faketime_str, TimeFromat))) if tmpformat is not None and tmpformat != '': cmd += ' --tmpformat "%s"' % tmpformat if tmpquality is not None and tmpquality != '': cmd += ' --tmpquality "%s"' % tmpquality if not autocolorspace: cmd += ' --noautocorr' if gamma != 1.0: cmd += ' -g %03f' % gamma if asp_in > 0.0: cmd += ' --aspect_in %f' % asp_in if fstart != -1: cmd += ' --fs %d' % fstart if fend != -1: cmd += ' --fe %d' % fend if fffirst: cmd += ' --fff' if not encodeonly: cmd += ' -r "%s"' % format if template is not None and template != '': cmd += ' -t "%s"' % template if slate is not None and slate != '': cmd += ' -s "%s"' % slate if company is not None and company != '': cmd += ' --company "%s"' % company if project is not None and project != '': cmd += ' --project "%s"' % project if shot is not None and shot != '': cmd += ' --shot "%s"' % shot if version is not None and version != '': cmd += ' --ver "%s"' % version if artist is not None and artist != '': cmd += ' --artist "%s"' % artist if activity is not None and activity != '': cmd += ' --activity "%s"' % activity if comments is not None and comments != '': cmd += ' --comments "%s"' % comments if draw169 is not None and draw169 != '': cmd += ' --draw169 "%s"' % draw169 if draw235 is not None and draw235 != '': cmd += ' --draw235 "%s"' % draw235 if line169 is not None and line169 != '': cmd += ' --line169 "%s"' % line169 if line235 is not None and line235 != '': cmd += ' --line235 "%s"' % line235 if line_clr is not None and line_clr != '': cmd += ' --line_aspect %f' % line_as cmd += ' --line_color "%s"' % line_clr if cach_op is not None and cach_op != '': cmd += ' --cacher_aspect %f' % cach_as cmd += ' --cacher_opacity "%s"' % cach_op if lgspath is not None and lgspath != '': cmd += ' --lgspath "%s"' % lgspath cmd += ' --lgssize %d' % lgssize cmd += ' --lgsgrav %s' % lgsgrav if lgfpath is not None and lgfpath != '': cmd += ' --lgfpath "%s"' % lgfpath cmd += ' --lgfsize %d' % lgfsize cmd += ' --lgfgrav %s' % lgfgrav if node.knob('stereodub').value(): cmd += ' --stereo' cmd += ' ' + images cmd += ' ' + os.path.join(os.path.abspath(movfolder), movname) return cmd
def render(self): render_name = self.ui.renderName.text() frame_range = self.ui.frameRange.text() chunk_size = self.ui.chunkComboBox.currentText() force_fullsize = self.ui.fullsizeCheckbox.isChecked() quiet_mode = self.ui.quietCheckbox.isChecked() thread_count = self.ui.threadSpinBox.value() if chunk_size == "None": chunk_size = 0 self.username = getpass.getuser() self.timestamp = int(time.time()) #username = "******" #timestamp = "123445677" if render_name is None: render_name = "Nuke Render for %s" % self.username try: spooldir = "/mnt/muxfs/users/%s/spool" % self.username # should be built from a template in cfg exists = utils.executeInMainThreadWithResult( os.path.exists, (spooldir, )) if not exists: utils.executeInMainThreadWithResult( os.makedirs, (spooldir, )) except: print "Warning. Attempt to create spool directory failed" filename = "nuke-%s-%s.nk" % (self.username, self.timestamp) filepath = os.path.join(spooldir, filename) try: utils.executeInMainThreadWithResult(nuke.scriptSave, (filepath, )) print filepath except: nuke.message("ERR-001 Unable to save spool file") nuke_args = { "type": "Nuke", "threads": thread_count, "fullsize": force_fullsize, "quiet": quiet_mode, "file": filepath, "nodes": self.selectedWriteNodes() } render_args = { "range": frame_range, "chunksize": chunk_size, "timestamp": self.timestamp, "name": render_name, "user": self.username, } print render_args print nuke_args launchRender(render_args, nuke_args) self.ui.close()
def __init__(self, afnode, wnode, subblock, prefix, fparams): if VERBOSE == 2: print('Initializing block parameters for "%s"' % wnode.name()) self.wnode = wnode self.valid = True self.subblock = subblock self.prefix = prefix self.framefirst = nuke.root().firstFrame() self.framelast = nuke.root().lastFrame() self.frameinc = 1 self.framespertask = 1 self.framesequential = 1 self.skipexisting = 0 self.maxruntasks = -1 self.capacity = -1 self.maxperhost = -1 self.maxruntime = -1 self.hostsmask = None self.hostsmaskexclude = None self.fullrangedepend = 0 self.tmpimage = 1 self.pathsmap = 1 self.imgfiles = [] self.tickets_use = 0 self.tickets_data = None # Just to add to the final job name some info, for example timecode self.jobname_suffix = '' if afnode is not None: self.framefirst = int(afnode.knob('framefirst').value()) self.framelast = int(afnode.knob('framelast').value()) self.frameinc = int(afnode.knob('frameinc').value()) self.framespertask = int(afnode.knob('framespertask').value()) self.framesequential = int(afnode.knob('framesequential').value()) self.skipexisting = int(afnode.knob('skipexisting').value()) self.maxruntasks = int(afnode.knob('maxruntasks').value()) self.capacity = int(afnode.knob('capacity').value()) self.maxperhost = int(afnode.knob('maxperhost').value()) self.maxruntime = int(afnode.knob('maxruntime').value()) self.tmpimage = int(afnode.knob('tmpimage').value()) self.pathsmap = int(afnode.knob('pathsmap').value()) self.hostsmask = afnode.knob('hostsmask').value() self.hostsmaskexclude = afnode.knob('hostsmaskexcl').value() self.tickets_use = int(afnode.knob('tickets_use').value()) self.tickets_data = afnode.knob('tickets_data').value() if int(afnode.knob('timecode_use').value()): timecode = afnode.knob('timecode').value() if len (timecode): frange = cgruutils.timecodesToFrameRange( timecode, nuke.root().fps()) if frange is None or frange[0] is None or frange[1] is None: nuke.message('Invalid timecode: "%s"' % timecode) return None self.framefirst = frange[0] self.framelast = frange[1] afnode.knob('timecode').setValue( cgruutils.timecodesFromFrameRange( frange[0], frange[1])) # Add timecode to a final job name: self.jobname_suffix += '.' + timecode.replace(' ','') if self.skipexisting: self.framespertask = 1 self.writename = str(wnode.fullName()) if wnode.Class() == RenderNodeClassName: afcommon = __import__('afcommon', globals(), locals(), []) # Get images files: if nuke.toNode('root').knob('proxy').value(): fileknob = wnode.knob('proxy') else: fileknob = wnode.knob('file') # Get views: views = wnode.knob('views') if views is not None: views = views.value() if views is None or views == '': views = nuke.views() else: views = views.split(' ') else: views = nuke.views() # Iterate views: for view in views: view = view.strip() if not len(view): continue # skip empty view, may be after split(' ') # Check view exists: if not view in nuke.views(): print('Error: Skipping invalid view: "%s"' % view) continue # if len( self.imgfiles): # self.imgfiles += ';' # Get show files for current view and first and last frames: octx = nuke.OutputContext() octx.setView(1 + nuke.views().index(view)) octx_framefirst = self.framefirst octx_framelast = self.framelast if octx_framefirst < 0: octx_framefirst = 0 if octx_framelast < 0: octx_framelast = 0 # If frame first and frame last are equal no sequence needed if octx_framefirst == octx_framelast: octx.setFrame(octx_framefirst) self.imgfiles.append(fileknob.getEvaluatedValue(octx)) else: # Get files from first and last frames # to calculate frames pattern: octx.setFrame(octx_framefirst) images1 = fileknob.getEvaluatedValue(octx) if images1 is None or images1 == '': nuke.message( 'Error:\n' '%s\n' 'Files are empty.\n' 'View "%s", frame %d.' % (self.writename, view, self.framefirst) ) self.valid = False return octx.setFrame(octx_framelast) images2 = fileknob.getEvaluatedValue(octx) if images2 is None or images2 == '': nuke.message( 'Error:\n' '%s\n' 'Files are empty.\n' 'View "%s", frame %d.' % (self.writename, view, self.framelast) ) self.valid = False return part1, padding, part2 = \ afcommon.splitPathsDifference(images1, images2) if padding < 1: nuke.message( 'Error:\n' '%s\n' 'Invalid files pattern.\n' 'View "%s".' % (self.writename, view) ) self.valid = False return self.imgfiles.append( '%s@%s@%s' % (part1, '#' * padding, part2) ) # Check images folders: for imgfile in self.imgfiles: folder = os.path.dirname(imgfile) if folder != '': if not os.path.isdir(folder): result = nuke.ask( 'Write Node "%s" Directory\n' '%s\n' 'Does not exist.\n' 'Create it?' % (self.writename, folder) ) if result: os.makedirs(folder) if not os.path.isdir(folder): nuke.message( "Can't create folder:\n%s" % folder ) self.valid = False else: self.valid = False elif wnode.Class() == DailiesNodeClassName: if VERBOSE: print('Generating dailies "%s"' % self.writename) else: nuke.message('Node type\n"%s"\nis unsendable.' % self.writename) self.valid = False for par in fparams: if fparams[par] is not None: if hasattr(self, par): setattr(self, par, fparams[par]) self.name = self.writename if subblock: if self.prefix is not None: if self.prefix != '': self.name = self.prefix + self.name self.dependmask = '' self.tasksdependmask = ''
def knobChanged(self, knob): ''' knob actions ''' # toggle show/hide renderpath file input if knob.name() == "writeEachStep": if self.writeEachStep.getValue() == 1: self.renderPath.setVisible(True) else: self.renderPath.setVisible(False) # remove all unchecked items if knob.name() == "removeUnchecked": deleteItems = [] #append all items to delete to array for k in nuke.BREAKDOWNKNOBS: if k.getValue() == 0: deleteItems.append(k.label()) # remove all selected knobs from GUI and from breakdownlist for deleteItem in deleteItems: for k in nuke.BREAKDOWNKNOBS: if deleteItem in k.label(): #remove knob from GUI self.removeKnob(k) #remove knob from array nuke.BREAKDOWNKNOBS.remove(k) #remove all selected from breakdownlist for deleteItem in deleteItems: for k in nuke.BREAKDOWNLIST: if k.name() in deleteItem: nuke.BREAKDOWNLIST.remove(k) #add selected knobs to breakdown list if knob.name() == "addToList": i = len(nuke.BREAKDOWNLIST) for node in nuke.selectedNodes(): if node not in nuke.BREAKDOWNLIST: if node.Class() != "Viewer": nuke.BREAKDOWNLIST.append(node) self.new = nuke.Boolean_Knob('breakdown_%d' % i, '%s' % node.name()) self.new.setFlag(nuke.STARTLINE) self.new.setValue(True) self.addKnob(self.new) nuke.BREAKDOWNKNOBS.append(self.new) else: pass else: nuke.message("%s is already in breakdown list" % node.name()) i += 1 #help if knob.name() == "www.leafpictures.de": url = 'http://www.leafpictures.de/breakdown' webbrowser.open_new(url) # start make breakdown if knob.name() == "execute": def executeBreakdown(): # sort based on y position in dag. the node that is most top goes in first sortedBreakdownlist = sortNodesByPosition(nuke.BREAKDOWNLIST) if len(sortedBreakdownlist) == 0: nuke.message( "Please select some nodes to your breakdown list.") elif len(sortedBreakdownlist) == 1: nuke.message("Please select more than one item.") else: breakdown(sortedBreakdownlist, self.writeEachStep.getValue(), self.renderPath.getValue()) if self.writeEachStep.getValue() == 1: if self.renderPath.getValue() != "": if os.path.isdir(self.renderPath.getValue()): executeBreakdown() else: nuke.message( "The render path is invalid. Please Choose another render path." ) else: nuke.message( "Please choose a render path if you want to render out individual breakdown images." ) else: executeBreakdown()