def _emit_log_message(self, handler, record): """ Emits a log to Nuke's Script Editor and Error Console. :param handler: Log handler that this message was dispatched from :type handler: :class:`~python.logging.LogHandler` :param record: Std python logging record :type record: :class:`~python.logging.LogRecord` """ msg = handler.format(record) # Sends the message to error console of the DCC if self.hiero_enabled: import hiero if record.levelno >= logging.ERROR: hiero.core.log.error(msg) elif record.levelno >= logging.WARNING: hiero.core.log.info(msg) elif record.levelno >= logging.INFO: hiero.core.log.info(msg) else: hiero.core.log.setLogLevel(hiero.core.log.kDebug) hiero.core.log.debug(msg) else: if record.levelno >= logging.CRITICAL: nuke.critical("Shotgun Critical: %s" % msg) elif record.levelno >= logging.ERROR: nuke.error("Shotgun Error: %s" % msg) elif record.levelno >= logging.WARNING: nuke.warning("Shotgun Warning: %s" % msg) # Sends the message to the script editor. print msg
def main(): ''' If we have a read node selected, lets run the batch rename! ''' try: # Grab the selected node's file input node = nuke.selectedNode() sequence = node['file'].value() except: nuke.message("Select a read node first") return # Check if we have a Read node selected if node.Class() != "Read": nuke.critical("\nYou fool, I can't rename a \"%s\" node!" %node.Class()) return # Good to go, display dialog p = BatchRenamePanel(sequence) result = p.showModalDialog() # Run the batch rename with what we've collected if result == True: batchRename(node, sequence, p.find.value(), p.replace.value())
def moveSelection(self, frames): p = self.selectedTrackItems[0].project() p.beginUndo('Move Selection') t = self.selectedTrackItems[0] # This is a strange function call, should be on the Sequence not TrackItem level! try: t.moveTrackItems(self.selectedTrackItems, frames) except RuntimeError: nuke.critical("Requested move rejected. Overlapping track items / negative times are forbidden.") p.endUndo()
def open_count_sheet(): # method variables s_show_root = None s_seq = None s_shot = None # determine if we have a valid IH pipeline script open, and we are being executed within the IH pipeline. # basically, the environment variable IH_SHOW_ROOT must be defined, and the Nuke script must have txt_ih_seq # and txt_ih_shot defined in the root. try: s_show_root = os.environ['IH_SHOW_ROOT'] s_seq = nuke.root().knob('txt_ih_seq').value() s_shot = nuke.root().knob('txt_ih_shot').value() except: nuke.critical( 'Method open_count_sheet() must be run while an In-House Nuke script is loaded.' ) return # build the count sheet directory based on values in the Nuke script and the system environment s_count_sheet_dir = os.path.join(s_show_root, s_seq, s_shot, "data", "count_sheet") print "INFO: Likely count sheet directory: %s" % s_count_sheet_dir if not os.path.exists(s_count_sheet_dir): nuke.critical("Count sheet directory at %s does not exist!" % s_count_sheet_dir) return # get all pdf files in the count sheet directory w/ modification times, sort by modification time descending l_countsheets = [ os.path.join(s_count_sheet_dir, fn) for fn in os.listdir(s_count_sheet_dir) if fn.endswith('.pdf') ] l_counts_mtimes = [(os.stat(path)[ST_MTIME], path) for path in l_countsheets] l_counts_mtimes_sorted = sorted(l_counts_mtimes) # return the latest count sheet, based on file modification time s_latest_count_sheet = l_counts_mtimes_sorted[-1][1] print "INFO: Latest count sheet appears to be %s." % s_latest_count_sheet # finally, call the platform-specific method to open and display a count sheet in the GUI if sys.platform == "darwin": subprocess.Popen(["/usr/bin/open", s_latest_count_sheet]) elif sys.platform == "linux2": subprocess.Popen(["/usr/bin/xdg-open", s_latest_count_sheet]) else: subprocess.Popen([ "START", "Count Sheet for shot %s" % s_shot, s_latest_count_sheet ])
def package_execute_threaded(s_nuke_script_path): progress_bar = nuke.ProgressTask("Packaging Script") progress_bar.setMessage("Initializing...") progress_bar.setProgress(0) s_nuke_exe_path = nuke.env['ExecutablePath'] # package_script.py has NOT been cleaned of show-specific code and hard-coded paths. # To-Do as of 2016-10-28. s_pyscript = os.path.join(os.path.dirname(os.environ['IH_SHOW_ROOT']), "SHARED", "lib", "nuke", "nuke_pipeline", "package_script.py") s_cmd = "%s -i -V 2 -t %s %s" % (s_nuke_exe_path, s_pyscript, s_nuke_script_path) s_err_ar = [] f_progress = 0.0 print "INFO: Beginning: %s" % s_cmd proc = subprocess.Popen(s_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) while proc.poll() is None: try: s_out = proc.stdout.readline() print s_out.rstrip() s_err_ar.append(s_out.rstrip()) if not s_out.find("INFO: copying file") == -1: s_line_ar = s_out.split(" ") (f_frame_cur, f_frame_tot, f_source_cur, f_source_tot) = (float(s_line_ar[3]), float(s_line_ar[5]), float(s_line_ar[8]), float(s_line_ar[10])) f_progress = ((f_frame_cur / f_frame_tot) * (1 / f_source_tot)) + ( (f_source_cur - 1) / f_source_tot) progress_bar.setMessage("Copying: %s" % s_line_ar[-1]) progress_bar.setProgress(int(f_progress * 100)) except IOError: print "IOError Caught!" var = traceback.format_exc() print var if proc.returncode != 0: s_errmsg = "" s_err = '\n'.join(s_err_ar) if s_err.find("FOUNDRY LICENSE ERROR REPORT") != -1: s_errmsg = "Unable to obtain a license for Nuke! Package execution fails, will not proceed!" else: s_errmsg = "An unknown error has occurred. Please check the STDERR log above for more information." nuke.critical(s_errmsg) else: print "INFO: Successfully completed script packaging."
def moveSelection(self, frames): p = self.selectedTrackItems[0].project() p.beginUndo('Move Selection') t = self.selectedTrackItems[0] # This is a strange function call, should be on the Sequence not TrackItem level! try: t.moveTrackItems(self.selectedTrackItems, frames) except RuntimeError: nuke.critical( "Requested move rejected. Overlapping track items / negative times are forbidden." ) p.endUndo()
def package_execute_threaded(s_nuke_script_path): # hard coded Nuke executable path, because we're classy like that progress_bar = nuke.ProgressTask("Packaging Script") progress_bar.setMessage("Initializing...") progress_bar.setProgress(0) s_nuke_exe_path = nuke.env['ExecutablePath'] # "/Applications/Nuke9.0v4/Nuke9.0v4.app/Contents/MacOS/Nuke9.0v4" s_pyscript = "/Volumes/monovfx/inhouse/zmonolith/SHARED/lib/nuke/nuke_pipeline/package_script.py" s_cmd = "%s -i -V 2 -t %s %s" % (s_nuke_exe_path, s_pyscript, s_nuke_script_path) s_err_ar = [] f_progress = 0.0 print "INFO: Beginning: %s" % s_cmd proc = subprocess.Popen(s_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) while proc.poll() is None: try: s_out = proc.stdout.readline() print s_out.rstrip() s_err_ar.append(s_out.rstrip()) if not s_out.find("INFO: copying file") == -1: s_line_ar = s_out.split(" ") (f_frame_cur, f_frame_tot, f_source_cur, f_source_tot) = ( float(s_line_ar[3]), float(s_line_ar[5]), float(s_line_ar[8]), float(s_line_ar[10])) f_progress = ((f_frame_cur / f_frame_tot) * (1 / f_source_tot)) + ((f_source_cur - 1) / f_source_tot) progress_bar.setMessage("Copying: %s" % s_line_ar[-1]) progress_bar.setProgress(int(f_progress * 100)) except IOError: print "IOError Caught!" var = traceback.format_exc() print var if proc.returncode != 0: s_errmsg = "" s_err = '\n'.join(s_err_ar) if s_err.find("FOUNDRY LICENSE ERROR REPORT") != -1: s_errmsg = "Unable to obtain a license for Nuke! Package execution fails, will not proceed!" else: s_errmsg = "An unknown error has occurred. Please check the STDERR log above for more information." nuke.critical(s_errmsg) else: print "INFO: Successfully completed script packaging."
def build_cc_nodes(): show_root = os.environ['IH_SHOW_ROOT'] config = ConfigParser.ConfigParser() config.read(os.environ['IH_SHOW_CFG_PATH']) cfg_shot_regexp = config.get(os.environ['IH_SHOW_CODE'], 'shot_regexp') cfg_sequence_regexp = config.get(os.environ['IH_SHOW_CODE'], 'sequence_regexp') cfg_lut = config.get(os.environ['IH_SHOW_CODE'], 'lut') show_lut = os.path.join(show_root, "SHARED", "lut", cfg_lut) shot_re = re.compile(cfg_shot_regexp) seq_re = re.compile(cfg_seq_regexp) active_node = nuke.selectedNode() if active_node == None: nuke.critical("Please select either a Read or a Write node.") return if not active_node.Class() in ['Read', 'Write']: nuke.critical("Please select either a Read or a Write node.") return io_path = active_node.knob('file').value() c_shot_match = shot_re.search(io_path) c_shot = None if c_shot_match: c_shot = c_shot_match.group(0) else: nuke.critical( "Can not find a valid shot name in file path for selected node.") return c_seq = seq_re.search(c_shot).group(0) cdl_path = os.path.join(show_root, c_seq, c_shot, "data", "cdl", "%s.cdl" % c_shot) if not os.path.exists(cdl_path): nuke.critical("Can not find a CDL file at %s." % cdl_path) return # create cdl nodes nd_cs1 = nuke.nodes.OCIOColorSpace() nd_cs1.knob("out_colorspace").setValue("AlexaV3LogC") nd_cs1.connectInput(0, active_node) nd_cdl = nuke.nodes.OCIOCDLTransform() nd_cdl.knob("read_from_file").setValue(True) nd_cdl.knob("file").setValue("%s" % cdl_path) nd_cdl.connectInput(0, nd_cs1) nd_lut = nuke.nodes.OCIOFileTransform() nd_lut.knob("file").setValue("%s" % show_lut) nd_lut.connectInput(0, nd_cdl) nd_cs2 = nuke.nodes.OCIOColorSpace() nd_cs2.knob("in_colorspace").setValue("rec709") nd_cs2.connectInput(0, nd_lut)
def is_singleaov(cls, path, start): import os path = path % start if "{stereo}" in path: for side in ["Left", "Right"]: _p = path.format(stereo=side) if os.path.isfile(_p): path = _p break else: message = "Stereo not found in: %s" % path nuke.critical(message) # This will pop-up a dialog raise RuntimeError(message) try: data = exrheader.read_exr_header(path) except Exception: cls.log.warning("EXR header read failed: %s" % path) return False return set(data["channels"]) in [{"R", "G", "B", "A"}, {"R", "G", "B"}]
def createCam_Cam_VraytoNuke(node): try: mDat = node.metadata() reqFields = [ 'exr/camera%s' % i for i in ('FocalLength', 'Aperture', 'Transform') ] if not set(reqFields).issubset(mDat): nuke.critical( 'No metadata for camera found! Please select a read node with EXR metadata from VRay!' ) return nuke.message( "Creating a camera node based on VRay metadata. This works specifically on VRay data coming from Maya!\n\nIf you get both focal and aperture as they are in the metadata, there's no guarantee your Nuke camera will have the same FOV as the one that rendered the scene (because the render could have been fit to horizontal, to vertical, etc). Nuke always fits to the horizontal aperture. If you set the horizontal aperture as it is in the metadata, then you should use the FOV in the metadata to figure out the correct focal length for Nuke's camera. Or, you could keep the focal as is in the metadata, and change the horizontal_aperture instead. I'll go with the former here. Set the haperture knob as per the metadata, and derive the focal length from the FOV." ) first = node.firstFrame() last = node.lastFrame() ret = nuke.getFramesAndViews('Create Camera from Metadata', '%s-%s' % (first, last)) if ret is None: return fRange = nuke.FrameRange(ret[0]) cam = nuke.createNode('Camera2') cam['useMatrix'].setValue(False) for k in ('focal', 'haperture', 'vaperture', 'translate', 'rotate'): cam[k].setAnimated() task = nuke.ProgressTask('Baking camera from meta data in %s' % node.name()) for curTask, frame in enumerate(fRange): if task.isCancelled(): break task.setMessage('processing frame %s' % frame) hap = node.metadata('exr/cameraAperture', frame) # get horizontal aperture fov = node.metadata('exr/cameraFov', frame) # get camera FOV focal = float(hap) / ( 2.0 * math.tan(math.radians(fov) * 0.5) ) # convert the fov and aperture into focal length width = node.metadata('input/width', frame) height = node.metadata('input/height', frame) aspect = float(width) / float( height) # calulate aspect ratio from width and height vap = float( hap) / aspect # calculate vertical aperture from aspect ratio cam['focal'].setValueAt(float(focal), frame) cam['haperture'].setValueAt(float(hap), frame) cam['vaperture'].setValueAt(float(vap), frame) matrixCamera = node.metadata('exr/cameraTransform', frame) # get camera transform data # create a matrix to shove the original data into matrixCreated = nuke.math.Matrix4() for k, v in enumerate(matrixCamera): matrixCreated[k] = v matrixCreated.rotateX( math.radians(-90) ) # this is needed for VRay, it's a counter clockwise rotation translate = matrixCreated.transform(nuke.math.Vector3( 0, 0, 0)) # get a vector that represents the camera translation rotate = matrixCreated.rotationsZXY( ) # give us xyz rotations from cam matrix (must be converted to degrees) cam['translate'].setValueAt(float(translate.x), frame, 0) cam['translate'].setValueAt(float(translate.y), frame, 1) cam['translate'].setValueAt(float(translate.z), frame, 2) cam['rotate'].setValueAt(float(math.degrees(rotate[0])), frame, 0) cam['rotate'].setValueAt(float(math.degrees(rotate[1])), frame, 1) cam['rotate'].setValueAt(float(math.degrees(rotate[2])), frame, 2) task.setProgress(int(float(curTask) / fRange.frames() * 100)) except: nuke.message('ERROR: Select a EXR from Max / VRay')
#Start by setting in place the nodes if len(hdrs) < 2: print 'Need to select more than 2 Read Nodes' else: positionsY = [float(node.ypos()) for node in hdrs] positionsX = [float(node.xpos()) for node in hdrs] avgY = sum(positionsY) / len(positionsY) avgX = sum(positionsX) /len(positionsX) #Order the Read nodes by file name---------------- for hdrNode in hdrs: if hdrNode['file'].value().split('.')[-1] not in ('hdr', 'HDR', 'Hdr'): nuke.critical('Wrong file format for %s' %hdrNode) else: print '_'*50 print 'Node being processed %s' %hdrNode['name'].value() avgX += hdrNode.width() / 10 hdrNode.setYpos(avgY) hdrNode.setXpos(avgX) #Grade nodes creation gradeNode = nuke.createNode('Grade') gradeNode.setInput(0, hdrNode) gradeNode.setYpos(gradeNode.ypos()+10) print '\tGrade node created : %s' %gradeNode #Crop nodes creation cropNode = nuke.createNode('Crop')
def render_delivery_threaded(ms_python_script, start_frame, end_frame, md_filelist): progress_bar = nuke.ProgressTask("Building Delivery") progress_bar.setMessage("Initializing...") progress_bar.setProgress(0) s_nuke_exe_path = nuke.env[ 'ExecutablePath'] # "/Applications/Nuke9.0v4/Nuke9.0v4.app/Contents/MacOS/Nuke9.0v4" s_pyscript = ms_python_script s_cmd = "%s -i -V 2 -c 2G -t %s" % (s_nuke_exe_path, s_pyscript) s_err_ar = [] f_progress = 0.0 print "INFO: Beginning: %s" % s_cmd proc = subprocess.Popen(s_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) while proc.poll() is None: try: s_out = proc.stdout.readline() s_err_ar.append(s_out.rstrip()) if s_out.find(".exr took") > -1 or s_out.find(".tif took") > -1: s_line_ar = s_out.split(" ") s_exr_frame = s_line_ar[1].split('.')[-2] i_exr_frame = int(s_exr_frame) f_duration = float(end_frame - start_frame + 1) f_progress = (float(i_exr_frame) - float(start_frame) + 1.0) / f_duration # print "INFO: Rendering: Frame %d"%i_exr_frame progress_bar.setMessage("Rendering: Frame %d" % i_exr_frame) progress_bar.setProgress(int(f_progress * 50)) except IOError: print "ERROR: IOError Caught!" var = traceback.format_exc() print var if proc.returncode != 0: s_errmsg = "" s_err = '\n'.join(s_err_ar) l_err_verbose = [] for err_line in s_err_ar: if err_line.find("ERROR") != -1: l_err_verbose.append(err_line) if s_err.find("FOUNDRY LICENSE ERROR REPORT") != -1: s_errmsg = "Unable to obtain a license for Nuke! Package execution fails, will not proceed!" else: s_errmsg = "Error(s) have occurred. Details:\n%s" % '\n'.join( l_err_verbose) nuke.critical(s_errmsg) else: print "INFO: Successfully completed delivery render." # copy the files d_expanded_list = {} for s_src in md_filelist: if s_src.find('*') != -1: l_imgseq = glob.glob(s_src) for s_img in l_imgseq: d_expanded_list[s_img] = os.path.join(md_filelist[s_src], os.path.basename(s_img)) else: d_expanded_list[s_src] = md_filelist[s_src] i_len = len(d_expanded_list.keys()) # copy all of the files to the destination volume. # alert the user if anything goes wrong. try: for i_count, source_file in enumerate(d_expanded_list.keys(), start=1): progress_bar.setMessage("Copying: %s" % os.path.basename(source_file)) if not os.path.exists(os.path.dirname( d_expanded_list[source_file])): os.makedirs(os.path.dirname(d_expanded_list[source_file])) shutil.copy(source_file, d_expanded_list[source_file]) f_progress = float(i_count) / float(i_len) progress_bar.setProgress(50 + int(f_progress * 50)) except: # e_type = sys.exc_info()[0] # e_msg = sys.exc_info()[1] # e_traceback = sys.exc_info()[2] nuke.critical(traceback.format_exc()) else: progress_bar.setProgress(100) progress_bar.setMessage("Done!") del progress_bar
def simulate(): origFrame = nuke.frame() n = nuke.thisNode() frameStart = int(n.knob('start').value()) frameEnd = int(n.knob('end').value()) totalFrames = int(frameEnd - frameStart + 1) cache_path = n['cache'].value() # Must be exr format file_dir, ext = os.path.splitext(cache_path) if ext != '.exr': cache_path = file_dir + '.exr' n['cache'].setValue(cache_path) # Must have frame numbering try: existing_simulation = os.path.exists(cache_path % frameStart) except TypeError: nuke.critical("Simulation cannot be executed for multiple frames.") return # Warn user if simulation is not going to overwrite extend_existing = n.knob('extend_existing').value() if extend_existing and not existing_simulation: if not nuke.ask( "No render on frame <b>%i</b> for sequence:\n\n<i>%s</i>\n\nSequences may not match.\nContinue?" % (frameStart, cache_path)): return elif existing_simulation and not extend_existing: if not nuke.ask( "Simulation will overwrite existing sequence:\n\n<i>%s</i>\n\nContinue?" % cache_path): return # Create directory if it doesn't exist directory = os.path.dirname(cache_path) if not os.path.exists(directory): os.makedirs(directory) writeWater = n.node('WriteWATER') cache = n.node('CACHE') task = nuke.ProgressTask("Simulating...") try: for frame in range(frameStart, frameStart + totalFrames): # Update taskbar task.setMessage("Frame %i of %i" % (frame, frameStart + totalFrames - 1)) progress = (float(frame - frameStart) / totalFrames) * 100 task.setProgress(int(progress)) # Abort option if task.isCancelled(): nuke.executeInMainThread(nuke.message, args=("Aborted!")) break # Skip existing frames if extend_existing and os.path.exists(cache_path % frame): continue # Render frame nuke.frame(frame) cache.knob('reload').execute() nuke.execute(writeWater, frame, frame) finally: del task cache.knob('reload').execute() nuke.frame(origFrame)