def __call__(self): """ Start the capture. """ writePath = self._customWritePath or self._defaultWritePath self._viewer['file'].setValue(writePath) # _performCleanup will remove whatever filepath is set in the self._viewer['file'] knob. # So if this changes between runs then the old files wont get cleaned up, probably # a bug. if self._doCleanup: self._performCleanup() try: nuke.executeMultiple((self._viewer, ), self._frameRange, self._selectedViews, False) except RuntimeError, msg: if msg.args[0][0:9] == "Cancelled": splitMsg = string.split(msg.args[0]) msg = """ Render did not complete, do you want to show the completed range ? Frame range %s contains %s frames but only %s finished. """ % (self._frameRange, splitMsg[3], splitMsg[1]) self._doFlipbook = nuke.ask(msg) else: nuke.message("Flipbook render failed:\n%s" % (msg.args[0], )) self._doFlipbook = False
def RenderSpecificFrames(): sRanges = nuke.getInput( "Enter frames ranges, separated by spaces. Ex: 4 10,20 100,150,2") print sRanges lRanges = sRanges.split() lNukeRanges = [] for sRange in lRanges: lRange = sRange.split(',') lRange = [int(i) for i in lRange] if len(lRange) == 0: continue elif len( lRange ) == 1: # Only start frame. Add end frame (same as start frame) and step (1). lRange.extend([lRange[0], 1]) elif len(lRange) == 2: # Start frame and End Frame. Add step (1) lRange.extend([1]) elif len(lRange) > 3: # 4 Elements. Error. nuke.message("Wrong format: %s. Cannot process 4 elements" % str(lRange)) return False lNukeRanges.append(lRange) print lNukeRanges nuke.executeMultiple(nuke.selectedNodes(), lNukeRanges)
def renderTmpFiles(self, node, seqDir, start, end, incr): log ("renderTmpFiles %s %s %s %s %s" % (node.name(), seqDir, start, end, incr)) """ if (start == end) : targetPath = seqDir + "/" + node.name() + (".%d." % start) + self.outputFileFormat else : targetPath = seqDir + "/" + node.name() + ".#." + self.outputFileFormat """ targetPath = seqDir + "/" + node.name() + ".#." + self.outputFileFormat log ("targetPath %s" % targetPath) # XXX handle proxy renders fieldname = "file" """ if self.proxy: fieldname = "proxy" """ nuke.Undo().disable() writeNode = nuke.nodes.Write (tile_color='0xff000000') writeNode[fieldname].setValue (targetPath) writeNode.setInput (0, node) ret = True try: nuke.executeMultiple((writeNode,), ([start, end, incr],)) except Exception, msg: nuke.message("Render failed:\n%s" % (msg,)) ret = False
def run(self): frame_ranges = nuke.FrameRanges(self._frameRange.value().split(',')) views = self._selectedViews() rootProxyMode = nuke.root().proxy() try: nuke.Undo().disable() nuke.root().setProxy(self._useProxy.value()) if (self.isBackgrounded()): print frame_ranges make_out(self._nodeSelection) nuke.executeBackgroundNuke( nuke.EXE_PATH, self._nodeSelection, frame_ranges, views, self._getBackgroundLimits(), continueOnError=self._continueOnError.value()) else: if (self.skipExisting()): nuke.addBeforeFrameRender(skippy, nodeClass='Write') else: nuke.removeBeforeFrameRender(skippy, nodeClass='Write') make_out(self._nodeSelection) nuke.executeMultiple( self._nodeSelection, frame_ranges, views, continueOnError=self._continueOnError.value()) except RuntimeError, e: if self._exceptOnError or e.args[0][ 0: 9] != "Cancelled": # TO DO: change this to an exception type raise
def run(self): if self.isTimelineWrite() and self._frameServerRender.value(): from hiero.ui.nuke_bridge.nukestudio import scriptSaveAndReRender scriptSaveAndReRender() return frame_ranges = nuke.FrameRanges(self._frameRange.value().split(',')) views = self._selectedViews() rootProxyMode = nuke.root().proxy() try: nuke.Undo().disable() nuke.root().setProxy(self._useProxy.value()) if (self.isBackgrounded()): nuke.executeBackgroundNuke( nuke.EXE_PATH, self._nodeSelection, frame_ranges, views, self._getBackgroundLimits(), continueOnError=self._continueOnError.value()) else: nuke.executeMultiple( self._nodeSelection, frame_ranges, views, continueOnError=self._continueOnError.value()) except RuntimeError, e: if self._exceptOnError or e.args[0][ 0: 9] != "Cancelled": # TO DO: change this to an exception type raise
def run(self): frame_ranges = nuke.FrameRanges( self._frameRange.value().split(',')) views = self._selectedViews() try: nuke.Undo().disable() if (self.isBackgrounded()): nuke.executeBackgroundNuke( nuke.EXE_PATH, self._nodeSelection, frame_ranges, views, self._getBackgroundLimits(), continueOnError=self._continueOnError.value()) elif self._termRender.value(): terminal_render(self._nodeSelection, frame_ranges, views, self._numInstances.value(), self._numThreads.value(), self._maxMem.value()) else: nuke.executeMultiple( self._nodeSelection, frame_ranges, views, continueOnError=self._continueOnError.value()) except RuntimeError, e: if self._exceptOnError or e.args[0][ 0: 9] != "Cancelled": # TO DO: change this to an exception type raise
def renderTmpFiles(self, node, seqDir, start, end, incr): log("renderTmpFiles %s %s %s %s %s" % (node.name(), seqDir, start, end, incr)) """ if (start == end) : targetPath = seqDir + "/" + node.name() + (".%d." % start) + self.outputFileFormat else : targetPath = seqDir + "/" + node.name() + ".#." + self.outputFileFormat """ targetPath = seqDir + "/" + node.name() + ".#." + self.outputFileFormat log("targetPath %s" % targetPath) # XXX handle proxy renders fieldname = "file" """ if self.proxy: fieldname = "proxy" """ nuke.Undo().disable() writeNode = nuke.nodes.Write(tile_color='0xff000000') writeNode[fieldname].setValue(targetPath) writeNode.setInput(0, node) ret = True try: nuke.executeMultiple((writeNode, ), ([start, end, incr], )) except Exception, msg: nuke.message("Render failed:\n%s" % (msg, )) ret = False
def _render(self, group_node, mov_path, png_path): """ Renders quickdaily node """ # setup quicktime output resolution width = self.get_setting("width", 1024) height = self.get_setting("height", 540) mov_reformat_node = group_node.node("mov_reformat") mov_reformat_node["box_width"].setValue(width) mov_reformat_node["box_height"].setValue(height) # setup output png path png_out = group_node.node("png_writer") png_path = png_path.replace(os.sep, "/") png_out["file"].setValue(png_path) # setup output quicktime path mov_out = group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # on the mac and windows, we use the quicktime codec # on linux, use ffmpeg if sys.platform == "win32" or sys.platform == "darwin": # apple photo-jpeg movie mov_out["file_type"].setValue('mov') mov_out["codec"].setValue('jpeg') mov_out["fps"].setValue(23.97599983) mov_out["settings"].setValue( "000000000000000000000000000019a7365616e0000000100000001000000000000018676696465000000010000000e00000000000000227370746c0000000100000000000000006a706567000000000018000003ff000000207470726c000000010000000000000000000000000017f9db00000000000000246472617400000001000000000000000000000000000000530000010000000100000000156d70736f00000001000000000000000000000000186d66726100000001000000000000000000000000000000187073667200000001000000000000000000000000000000156266726100000001000000000000000000000000166d70657300000001000000000000000000000000002868617264000000010000000000000000000000000000000000000000000000000000000000000016656e647300000001000000000000000000000000001663666c67000000010000000000000000004400000018636d66720000000100000000000000006170706c00000014636c75740000000100000000000000000000001c766572730000000100000000000000000003001c00010000" ) elif sys.platform == "linux2": mov_out["file_type"].setValue("ffmpeg") mov_out["codec"].setValue("MOV format (mov)") # turn on the nodes mov_out.knob('disable').setValue(False) png_out.knob('disable').setValue(False) # finally render everything! # default to using the first view on stereo try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out, png_out], ([self._get_first_frame() - 1, self._get_last_frame(), 1], ), [first_view]) finally: # turn off the nodes again mov_out.knob('disable').setValue(True) png_out.knob('disable').setValue(True)
def _render(self, group_node, mov_path, png_path): """ Renders quickdaily node """ # setup quicktime output resolution width = self.get_setting("width", 1024) height = self.get_setting("height", 540) mov_reformat_node = group_node.node("mov_reformat") mov_reformat_node["box_width"].setValue(width) mov_reformat_node["box_height"].setValue(height) # setup output png path png_out = group_node.node("png_writer") png_path = png_path.replace(os.sep, "/") png_out["file"].setValue(png_path) # setup output quicktime path mov_out = group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # on the mac and windows, we use the quicktime codec # on linux, use ffmpeg if sys.platform == "win32" or sys.platform == "darwin": # apple photo-jpeg movie mov_out["file_type"].setValue('mov') mov_out["codec"].setValue('jpeg') mov_out["fps"].setValue(23.97599983) mov_out["settings"].setValue("000000000000000000000000000019a7365616e0000000100000001000000000000018676696465000000010000000e00000000000000227370746c0000000100000000000000006a706567000000000018000003ff000000207470726c000000010000000000000000000000000017f9db00000000000000246472617400000001000000000000000000000000000000530000010000000100000000156d70736f00000001000000000000000000000000186d66726100000001000000000000000000000000000000187073667200000001000000000000000000000000000000156266726100000001000000000000000000000000166d70657300000001000000000000000000000000002868617264000000010000000000000000000000000000000000000000000000000000000000000016656e647300000001000000000000000000000000001663666c67000000010000000000000000004400000018636d66720000000100000000000000006170706c00000014636c75740000000100000000000000000000001c766572730000000100000000000000000003001c00010000") elif sys.platform == "linux2": mov_out["file_type"].setValue("ffmpeg") mov_out["format"].setValue("MOV format (mov)") # turn on the nodes mov_out.knob('disable').setValue(False) png_out.knob('disable').setValue(False) # finally render everything! # default to using the first view on stereo try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out, png_out], ([ self._get_first_frame()-1, self._get_last_frame(), 1 ],), [first_view] ) finally: # turn off the nodes again mov_out.knob('disable').setValue(True) png_out.knob('disable').setValue(True)
def _render(self, mov_path, start_frame, end_frame): """ Renders write node :param mov_path: temporary path where quicktime should be written :param int start_frame: First frame to render :param int end_frame: Last frame to render """ import nuke # setup quicktime output resolution (width, height) = self._bundle.execute_hook_method( "settings_hook", "get_resolution", base_class=self._bundle.base_hooks.ReviewSettings ) mov_reformat_node = self._group_node.node("mov_reformat") mov_reformat_node["box_width"].setValue(width) mov_reformat_node["box_height"].setValue(height) # setup output quicktime path mov_out = self._group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # apply the Write node codec settings we'll use for generating the Quicktime self._bundle.execute_hook_method( "settings_hook", "setup_quicktime_node", write_node=mov_out, base_class=self._bundle.base_hooks.ReviewSettings ) # turn on the node mov_out.knob("disable").setValue(False) # render everything - default to using the first view on stereo logger.debug("Rendering quicktime") try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out], ([start_frame - 1, end_frame, 1],), [first_view] ) finally: # turn off the nodes again mov_out.knob("disable").setValue(True)
def run(self): frame_ranges = nuke.FrameRanges(self._frameRange.value().split(',')) views = self._selectedViews() rootProxyMode = nuke.root().proxy() try: nuke.Undo().disable() nuke.root().setProxy(self._useProxy.value()) nuke.executeMultiple(self._nodeSelection, frame_ranges, views, continueOnError=self._continueOnError.value()) except RuntimeError, e: if self._exceptOnError or e.args[0][ 0: 9] != "Cancelled": # TO DO: change this to an exception type raise
def _render(self, group_node, mov_path, png_path): """ Renders quickdaily node """ # setup quicktime output resolution # width = self.get_setting("width", 1024) # height = self.get_setting("height", 540) # mov_reformat_node = group_node.node("mov_reformat") # mov_reformat_node["box_width"].setValue(width) # mov_reformat_node["box_height"].setValue(height) # setup output png path png_out = group_node.node("png_writer") png_path = png_path.replace(os.sep, "/") png_out["file"].setValue(png_path) # setup output quicktime path mov_out = group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # MDS - Disabled codec settings. Defined in Gizmo now instead # apply the Write node codec settings we'll use for generating the Quicktime # self.execute_hook_method("codec_settings_hook", # "get_quicktime_settings", # write_node=mov_out) # turn on the nodes mov_out.knob('disable').setValue(False) png_out.knob('disable').setValue(False) # finally render everything! # default to using the first view on stereo try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out, png_out], ([self._get_first_frame(), self._get_last_frame(), 1], ), [first_view]) finally: # turn off the nodes again mov_out.knob('disable').setValue(True) png_out.knob('disable').setValue(True)
def testUVMapping(self): nuke.scriptOpen("test/IECoreNuke/scripts/sceneCacheTestUV.nk") w = nuke.toNode("Write1") frames = [1, 10, 20, 30, 40, 50] nuke.executeMultiple([w], map(lambda f: (f, f, 1), frames)) for f in frames: imageA = IECore.Reader.create( "test/IECoreNuke/scripts/data/sceneCacheExpectedUVResults.%04d.exr" % f)() imageB = IECore.Reader.create( "test/IECoreNuke/scripts/data/sceneCacheTestUVResults.%04d.exr" % f)() self.assertEqual( IECoreImage.ImageDiffOp()(imageA=imageA, imageB=imageB, maxError=0.05).value, False)
def cache_particles_panel(particleCacheNode): particleCacheNode.knobs()["particle_cache_render_in_progress"].setValue( True) try: nuke.Undo().disable() rootNode = nuke.root() firstFrame = rootNode['first_frame'].getValue() lastFrame = rootNode['last_frame'].getValue() # Extra frames added for motion blur padding = int(particleCacheNode['particle_cache_padding'].getValue()) nuke.executeMultiple( (particleCacheNode, ), ([firstFrame - padding, lastFrame + padding, 1], )) except RuntimeError, e: nuke.tprint(e) if e.args[0][ 0:9] != "Cancelled": # TO DO: change this to an exception type raise
def _render(self, group_node, mov_path, png_path): """ Renders quickdaily node """ # setup quicktime output resolution width = self.get_setting("width", 1024) height = self.get_setting("height", 540) mov_reformat_node = group_node.node("mov_reformat") mov_reformat_node["box_width"].setValue(width) mov_reformat_node["box_height"].setValue(height) # setup output png path png_out = group_node.node("png_writer") png_path = png_path.replace(os.sep, "/") png_out["file"].setValue(png_path) # setup output quicktime path mov_out = group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # apply the Write node codec settings we'll use for generating the Quicktime self.execute_hook_method("codec_settings_hook", "get_quicktime_settings", write_node=mov_out) # turn on the nodes mov_out.knob('disable').setValue(False) png_out.knob('disable').setValue(False) # finally render everything! # default to using the first view on stereo try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out, png_out], ([ self._get_first_frame()-1, self._get_last_frame(), 1 ],), [first_view] ) finally: # turn off the nodes again mov_out.knob('disable').setValue(True) png_out.knob('disable').setValue(True)
def testLoadedScriptWithRetime( self ) : nuke.scriptOpen("test/IECoreNuke/scripts/sceneCacheTest.nk" ) w = nuke.toNode("Write1") frames = [ 1, 10, 20, 30, 40, 50, 60, 70, 80 ] nuke.executeMultiple( [ w ], map( lambda f: (f,f,1), frames ) ) for f in frames : imageA = IECore.Reader.create( "test/IECoreNuke/scripts/data/sceneCacheExpectedResults.%04d.exr" % f )() imageB = IECore.Reader.create( "test/IECoreNuke/scripts/data/sceneCacheTestResults.%04d.exr" % f )() self.assertEqual( IECore.ImageDiffOp()( imageA = imageA, imageB = imageB, maxError = 0.05 ).value, False ) n = nuke.toNode("ieSceneCacheReader4") v = n.knob('sceneView') self.assertEqual( set(v.getSelectedItems()), set(['/root/A/a']) ) # now force loading A+B and test in frame 20 v.setSelectedItems(['/root/A/a', '/root/B/b', '/root/bezier1', '/root/particle1']) self.assertEqual( set(v.getSelectedItems()), set(['/root/A/a', '/root/B/b', '/root/bezier1', '/root/particle1' ]) ) nuke.executeMultiple( [ w ], [(20,20,1)] ) imageA = IECore.Reader.create( "test/IECoreNuke/scripts/data/sceneCacheExpectedResultsB.0020.exr" )() imageB = IECore.Reader.create( "test/IECoreNuke/scripts/data/sceneCacheTestResults.0020.exr" )() self.assertEqual( IECore.ImageDiffOp()( imageA = imageA, imageB = imageB, maxError = 0.05 ).value, False )
def autocropLayers(self, first=None, last=None, inc=None, layer="rgba"): root = nuke.root() if first is None: first = int(root.knob("first_frame").value()) if last is None: last = int(root.knob("first_frame").value()) if inc is None: inc = 1 original_nodes = nuke.selectedNodes() all_nodes = nuke.allNodes() for i in all_nodes: i.knob("selected").setValue(False) for i in original_nodes: i.knob("selected").setValue(True) autocropper = nuke.createNode("CurveTool", '''operation 0 ROI {0 0 input.width input.height} Layer %s label "Processing Crop..." selected true''' % (str(layer), ), False) nuke.executeMultiple([autocropper,], ([first, last, inc],)) autocropper.knob("selected").setValue(True) cropnode = nuke.createNode("Crop", "label AutoCrop", False) cropbox = cropnode.knob("box"); autocropbox = autocropper.knob("autocropdata"); cropbox.copyAnimations(autocropbox.animations()) cropnode.knob("indicators").setValue(1) all_nodes = nuke.allNodes() for j in all_nodes: j.knob("selected").setValue(False) autocropper.knob("selected").setValue(True) nukescripts.node_delete() all_nodes = nuke.allNodes() for j in all_nodes: j.knob("selected").setValue(False) nuke.autoplace(cropnode) cropnode.knob("selected").setValue(True) cropnode.knob("reformat").setValue(True) nuke.autoplace(cropnode) return cropnode
def runRender(renderOpts): root = nuke.root() if root.name() == "Root": ueNukeSave.ueSaveAs() sourceSpec = ueSpec.Spec( root.knob("ueproj").value(), root.knob("uegrp").value(), root.knob("ueasst").value(), root.knob("ueclass").value(), root.knob("uetype").value(), root.knob("uename").value(), root.knob("uevers").value()) writeNodes = [] frameRanges = [] for i, writeNode in enumerate(renderOpts[1]): n = nuke.toNode(writeNode) destSpec = ueSpec.Spec( n.knob("proj").value(), n.knob("grp").value(), n.knob("asst").value(), n.knob("elclass").value(), n.knob("eltype").value(), n.knob("elname").value()) # Create the element(s)/version(s) to render into dbMeta = {} e = ueAssetUtils.getElement(destSpec) if e == {}: e = ueCreate.createElement(destSpec, dbMeta=dbMeta) # If we're rendering into the last existing version, delete it if not renderOpts[2]["newVersion"]: versions = ueAssetUtils.getVersions(destSpec) destSpec.vers = len(versions) ueDestroy.destroyVersion(destSpec) if renderOpts[2]["clearLastVersion"]: nuke.tprint("deleting files") # Create a new version dbMeta["comment"] = "Render from %s" % str(sourceSpec) v = ueCreate.createVersion(destSpec, dbMeta=dbMeta) destSpec.vers = v["version"] path = v["path"] name = v["file_name"] # Set up the write nodes with the correct paths p = os.path.join(path, name + ".%04d." + n.knob("file_type").value()) n.knob("file").setValue(p) # Get the frame range from the ueWrite gizmo, else default to # the scripts asset settings first = nuke.root().knob("first_frame").value() last = nuke.root().knob("last_frame").value() if n.knob("use_limit").value(): first = n.knob("first").value() last = n.knob("last").value() writeNodes.append(n) if i == 0: frameRanges.append((int(first), int(last), 1)) else: frameRanges.append((int(first), int(first), 1)) dbMeta = {} dbMeta["comment"] = "Auto-save of render %s" % str(destSpec) ueNukeUtils.saveUtility(sourceSpec, dbMeta=dbMeta) ueNukeUtils.saveUtility(sourceSpec) # Render # 0 = Standard nuke "interactive" render # 1 = DrQueue render farm (os.system is a little weird, but it's # so you don't have to compile it's python module for nuke) # 2 = Cloud render farm, maybe sometime in the future if renderOpts[0] == 0: nuke.tprint("Rendering %s ..." % str(destSpec)) # execute() takes a string for the node name, executeMultiple() takes a tuple of node objects if len(writeNodes) == 1: nuke.execute(writeNodes[0].name(), frameRanges[0][0], frameRanges[0][1], frameRanges[0][2]) else: nuke.executeMultiple(tuple(writeNodes), tuple(frameRanges)) elif renderOpts[0] == 1: nuke.tprint("Spooling %s ..." % str(destSpec)) sourceSpec.vers = sourceSpec.vers - 1 options = {} options["writeNode"] = [] for render in renderOpts[1]: n = nuke.toNode(render) options["writeNode"].append(n.name()) p = os.path.join(os.getenv("UE_PATH"), "src", "ueRender", "Spool.py") os.system("python %s %s %s nuke %i %i '%s'" % (p, str(sourceSpec), str(destSpec), int(first), int(last), json.dumps(options))) elif renderOpts[0] == 2: nuke.tprint("Spooling to cloud currently not avaliable")
def _render(self, mov_path, start_frame, end_frame): """ Renders write node :param mov_path: temporary path where quicktime should be written :param int start_frame: First frame to render :param int end_frame: Last frame to render """ import nuke # setup quicktime output resolution (width, height) = self._bundle.execute_hook_method( "settings_hook", "get_resolution", base_class=self._bundle.base_hooks.ReviewSettings, ) #mov_reformat_node = self._group_node.node("mov_reformat") #mov_reformat_node["box_width"].setValue(width) #mov_reformat_node["box_height"].setValue(height) # setup output quicktime path mov_out = self._group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # setting output colorspace colorspace = nuke.root().knob('colorManagement').getValue() # If OCIO is set, output - sRGB if colorspace: mov_out.knob('colorspace').setValue('Output - sRGB') # If no OCIO is set, detect if ACES is used or nuke_default else: ocio_config = nuke.root().knob('OCIO_config').getValue() if ocio_config == 2.0: mov_out.knob('colorspace').setValue('sRGB') else: mov_out.knob('colorspace').setValue('Output - sRGB') # apply the Write node codec settings we'll use for generating the Quicktime self._bundle.execute_hook_method( "settings_hook", "setup_quicktime_node", write_node=mov_out, base_class=self._bundle.base_hooks.ReviewSettings, ) # turn on the node mov_out.knob("disable").setValue(False) # render everything - default to using the first view on stereo logger.debug("Rendering quicktime") try: first_view = nuke.views()[0] nuke.executeMultiple([mov_out], ([start_frame - 1, end_frame, 1], ), [first_view]) finally: # turn off the nodes again mov_out.knob("disable").setValue(True)
def _render_movie_in_nuke(self, fields, path, output_path, width, height, first_frame, last_frame): """ Use Nuke to render a movie. This assumes we're running _inside_ Nuke. """ output_node = None # create group where everything happens group = nuke.nodes.Group() # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=path) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) # now create the slate/burnin node burn = nuke.nodePaste(self._burnin_nk) burn.setInput(0, read) # set the fonts for all text fields burn.node("top_left_text")["font"].setValue(self._font) burn.node("top_right_text")["font"].setValue(self._font) burn.node("bottom_left_text")["font"].setValue(self._font) burn.node("framecounter")["font"].setValue(self._font) burn.node("slate_info")["font"].setValue(self._font) # add the logo burn.node("logo")["file"].setValue(self._logo) # format the burnins version_padding_format = "%%0%dd" % self.get_setting("version_number_padding") version_str = version_padding_format % fields.get("version", 0) if self.context.task: version = "%s, v%s" % (self.context.task["name"], version_str) elif self.context.step: version = "%s, v%s" % (self.context.step["name"], version_str) else: version = "v%s" % version_str burn.node("top_left_text")["message"].setValue(self.context.project["name"]) burn.node("top_right_text")["message"].setValue(self.context.entity["name"]) burn.node("bottom_left_text")["message"].setValue(version) # and the slate slate_str = "Project: %s\n" % self.context.project["name"] slate_str += "%s: %s\n" % (self.context.entity["type"], self.context.entity["name"]) slate_str += "Name: %s\n" % fields.get("name", "Unnamed").capitalize() slate_str += "Version: %s\n" % version_str if self.context.task: slate_str += "Task: %s\n" % self.context.task["name"] elif self.context.step: slate_str += "Step: %s\n" % self.context.step["name"] slate_str += "Frames: %s - %s\n" % (first_frame, last_frame) burn.node("slate_info")["message"].setValue(slate_str) # create a scale node scale = self._create_scale_node(width, height) scale.setInput(0, burn) # Create the output node output_node = self._create_output_node(output_path) output_node.setInput(0, scale) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(output_path) self.ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame - 1, last_frame, 1],), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group)
def autocrop(first=None, last=None, inc=None, layer="rgba"): """Run the CurveTool's AutoCrop function on each selected node over the specified frame range and channels. If the range values are None, the project first_frame and last_frame are used; if inc is None, 1 is used. After execution, the CurveTool AutoCrop results are copied into a Crop node attached to each selected node.""" # Sort out execute range root = nuke.root() if first is None: first = int(root.knob("first_frame").value()) if last is None: last = int(root.knob("last_frame").value()) if inc is None: inc = 1 # 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) autocropper = nuke.createNode( "CurveTool", '''operation 0 ROI {0 0 input.width input.height} 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() # 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 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 render( self, input_path, output_path, width, height, first_frame, last_frame, version, name, color_space, ): """ Use Nuke to render a movie. :param str input_path: Path to the input frames for the movie :param str output_path: Path to the output movie that will be rendered :param int width: Width of the output movie :param int height: Height of the output movie :param int first_frame: The first frame of the sequence of frames. :param int last_frame: The last frame of the sequence of frames. :param str version: Version number to use for the output movie slate and burn-in :param str name: Name to use in the slate for the output movie :param str color_space: Colorspace of the input frames :returns: Location of the rendered media :rtype: str """ output_node = None ctx = self.__app.context # create group where everything happens group = nuke.nodes.Group() # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=input_path.replace(os.sep, "/")) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) if color_space: read["colorspace"].setValue(color_space) # now create the slate/burnin node burn = nuke.nodePaste(self._burnin_nk) burn.setInput(0, read) # set the fonts for all text fields burn.node("top_left_text")["font"].setValue(self._font) burn.node("top_right_text")["font"].setValue(self._font) burn.node("bottom_left_text")["font"].setValue(self._font) burn.node("framecounter")["font"].setValue(self._font) burn.node("slate_info")["font"].setValue(self._font) # add the logo burn.node("logo")["file"].setValue(self._logo) # format the burnins version_padding_format = "%%0%dd" % self.__app.get_setting( "version_number_padding" ) version_str = version_padding_format % version if ctx.task: version_label = "%s, v%s" % (ctx.task["name"], version_str) elif ctx.step: version_label = "%s, v%s" % (ctx.step["name"], version_str) else: version_label = "v%s" % version_str burn.node("top_left_text")["message"].setValue(ctx.project["name"]) burn.node("top_right_text")["message"].setValue(ctx.entity["name"]) burn.node("bottom_left_text")["message"].setValue(version_label) # and the slate slate_str = "Project: %s\n" % ctx.project["name"] slate_str += "%s: %s\n" % (ctx.entity["type"], ctx.entity["name"]) slate_str += "Name: %s\n" % name.capitalize() slate_str += "Version: %s\n" % version_str if ctx.task: slate_str += "Task: %s\n" % ctx.task["name"] elif ctx.step: slate_str += "Step: %s\n" % ctx.step["name"] slate_str += "Frames: %s - %s\n" % (first_frame, last_frame) burn.node("slate_info")["message"].setValue(slate_str) # create a scale node scale = self.__create_scale_node(width, height) scale.setInput(0, burn) # Create the output node output_node = self.__create_output_node(output_path) output_node.setInput(0, scale) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(output_path) self.__app.ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple( [output_node], ([first_frame - 1, last_frame, 1],), [nuke.views()[0]] ) # Cleanup after ourselves nuke.delete(group) return output_path
def runRender(renderOpts): root = nuke.root() if root.name() == "Root": ueNukeSave.ueSaveAs() sourceSpec = ueSpec.Spec(root.knob("ueproj").value(), root.knob("uegrp").value(), root.knob("ueasst").value(), root.knob("ueclass").value(), root.knob("uetype").value(), root.knob("uename").value(), root.knob("uevers").value()) writeNodes = [] frameRanges = [] for i, writeNode in enumerate(renderOpts[1]): n = nuke.toNode(writeNode) destSpec = ueSpec.Spec(n.knob("proj").value(), n.knob("grp").value(), n.knob("asst").value(), n.knob("elclass").value(), n.knob("eltype").value(), n.knob("elname").value()) # Create the element(s)/version(s) to render into dbMeta = {} e = ueAssetUtils.getElement(destSpec) if e == {}: e = ueCreate.createElement(destSpec, dbMeta=dbMeta) # If we're rendering into the last existing version, delete it if not renderOpts[2]["newVersion"]: versions = ueAssetUtils.getVersions(destSpec) destSpec.vers = len(versions) ueDestroy.destroyVersion(destSpec) if renderOpts[2]["clearLastVersion"]: nuke.tprint("deleting files") # Create a new version dbMeta["comment"] = "Render from %s" % str(sourceSpec) v = ueCreate.createVersion(destSpec, dbMeta=dbMeta) destSpec.vers = v["version"] path = v["path"] name = v["file_name"] # Set up the write nodes with the correct paths p = os.path.join(path, name+".%04d."+n.knob("file_type").value()) n.knob("file").setValue(p) # Get the frame range from the ueWrite gizmo, else default to # the scripts asset settings first = nuke.root().knob("first_frame").value() last = nuke.root().knob("last_frame").value() if n.knob("use_limit").value(): first = n.knob("first").value() last = n.knob("last").value() writeNodes.append(n) if i == 0: frameRanges.append((int(first), int(last), 1)) else: frameRanges.append((int(first), int(first), 1)) dbMeta = {} dbMeta["comment"] = "Auto-save of render %s" % str(destSpec) ueNukeUtils.saveUtility(sourceSpec, dbMeta=dbMeta) ueNukeUtils.saveUtility(sourceSpec) # Render # 0 = Standard nuke "interactive" render # 1 = DrQueue render farm (os.system is a little weird, but it's # so you don't have to compile it's python module for nuke) # 2 = Cloud render farm, maybe sometime in the future if renderOpts[0] == 0: nuke.tprint("Rendering %s ..." % str(destSpec)) # execute() takes a string for the node name, executeMultiple() takes a tuple of node objects if len(writeNodes) == 1: nuke.execute(writeNodes[0].name(), frameRanges[0][0], frameRanges[0][1], frameRanges[0][2]) else: nuke.executeMultiple(tuple(writeNodes), tuple(frameRanges)) elif renderOpts[0] == 1: nuke.tprint("Spooling %s ..." % str(destSpec)) sourceSpec.vers = sourceSpec.vers-1 options = {} options["writeNode"] = [] for render in renderOpts[1]: n = nuke.toNode(render) options["writeNode"].append(n.name()) p = os.path.join(os.getenv("UE_PATH"), "src", "ueRender", "Spool.py") os.system("python %s %s %s nuke %i %i '%s'" % (p, str(sourceSpec), str(destSpec), int(first), int(last), json.dumps(options))) elif renderOpts[0] == 2: nuke.tprint("Spooling to cloud currently not avaliable")
burn.node("bottom_left_text")["message"].setValue(file_name) burn.node("bottom_center_text")["message"].setValue(project_name) # slate project info burn.node("slate_projectinfo")["message"].setValue(project_name) slate_str = "%s\n" % file_name slate_str += "%s - %s\n" % (first_frame, last_frame) slate_str += "%s\n" % date_formatted slate_str += "%s\n" % user_name slate_str += "v%s\n \n" % version_str slate_str += "%s\n" % fps slate_str += "%s\n" % resolution burn.node("slate_info")["message"].setValue(slate_str) # Create the output node output_node = __create_output_node(outputPath) output_node.setInput(0, burn) finally: group.end() if output_node: # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame - 1, last_frame, 1], ), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group)
start = int(nuke.numvalue("root.first_frame")) end = int(nuke.numvalue("root.last_frame")) incr = 1 if start < 1: nuke.message("Start frame number cannot be less than 1") return try: _range = str(nuke.FrameRange(start, end, incr)) except ValueError,e: # In this case we have to extract from the error message the # correct frame range format string representation. # I'm expecting to have an error like: "Frame Range invalid (-1722942,-1722942)" msg = e. __str__() _range = msg[msg.index("(")+1: msg.index(")")] r = nuke.getInput("Frames to render:", _range) if r is not None: frame_ranges = nuke.FrameRanges(r) if nuke.thisNode()['slate'].value() is True: frame_ranges.add(nuke.FrameRange(start - 1, start - 1, 1)) frame_ranges.compact() nuke.tprint(frame_ranges) try: nuke.executeMultiple(_list, frame_ranges) except RuntimeError, e: if exceptOnError or e.message[0:9] != "Cancelled": # TO DO: change this to an exception type raise
proxyWrt.knob("file_type").setValue( 'exr' ) proxyWrt.knob("compression").setValue( "PIZ Wavelet (32 scanlines)" ) print start proxyWrt.knob('first').setValue(float(start)) proxyWrt.knob('last').setValue(float(end)) #proxyWrt.knob('use_limit').setValue(True) #render srfm, efrm #outputs =either of the write nodes if they have an input connection outputs = [x for x in [nukeNodes['writeLin']['node'], nukeNodes['writeProxy']['node']] if x.input(0) ] if outputs: #nuke.executeMultiple ((variable,), ([start,end,incr],)) #nuke.executeMultiple([w, w2,], ([start - 1,stop,1],)) print "Rendering: %s start=%s end=%s" %( str(outputs), str(start), str(end) ) nuke.executeMultiple(outputs, ([int(start),int(end), 1],)) #nuke.execute(nukeNodes['writeLin']['node'], int(start), int(end)) #nuke.execute(nukeNodes['writeProxy']['node'], int(start), int(end)) return True else: print "ERROR: No putput nodes connected" return False else: print "Input and working are identical. No operation" return True # NUKE NODE CODE ----------------------------------------------------------------------------------------------------------------- def nodeFactory(nodeDict): ''' a node creator. Pass a dict with 'nodeType'<str>, 'args'<list> and 'kwargs'<dict> keys
def _createIntermediateNode(self): """Create a write node to render out the current node so that output may be used for flipbooking.""" flipbooktmp = self._getIntermediatePath() fieldname = "file" if self._useProxy.value(): fieldname = "proxy" fixup = nuke.createNode("Group", "tile_color 0xff000000", inpanel=False) with fixup: fixup.setName("Flipbook") inputNode = nuke.createNode("Input", inpanel=False) shuffle = nuke.createNode("Shuffle", inpanel=False) shuffle.knob("in").setValue(self._channels.value()) if self._useRoi.value(): crop = nuke.createNode("Crop", inpanel=False) crop['box'].fromScript(self._roi.toScript()) write = nuke.createNode("Write", fieldname + " {" + flipbooktmp + "}", inpanel=False) write.knob('file_type').setValue(self._getIntermediateFileType()) selectedViews = self._selectedViews() write.knob('views').fromScript(" ".join(selectedViews)) if self._getIntermediateFileType() == "exr": write.knob('compression').setValue("B44") # Set the 'heroview' to be the first of the selected views. If we don't # do this then then 'heroview' is by default set to be 1 which may not # be a valid view for this clip. The 'heroview' is used as a fallback if # no view has been set on the reader. This assumes the user has selected # sensible views if they haven't then the write may still fail. if len(selectedViews) > 0: firstView = nuke.OutputContext().viewFromName( selectedViews[0]) write.knob('heroview').setValue(firstView) writeColorspace = "" if self._burnInLUT.value(): # The user has chosen to burn the viewer transform into the intermedate render so set the colorspace # on the Write node appropriately. writeColorspace = self._getBurninWriteColorspace() else: # The viewer transform is not being burnt into the intermediate render, set the Write node's colorspace # to whatever the current working space is - when reading the file back in the flipbook we'll ssume # the media was written out in the working space. rootNode = nuke.root() if rootNode: workingSpaceKnob = rootNode.knob("workingSpaceLUT") if workingSpaceKnob: writeColorspace = workingSpaceKnob.value() if writeColorspace: write.knob('colorspace').setValue(writeColorspace) outputNode = nuke.createNode("Output", inpanel=False) #If called on a Viewer connect fixup node to the one immediately above if exists. if self._node.Class() == "Viewer": fixup.setInput( 0, self._node.input( int(nuke.knob(self._node.fullName() + ".input_number")))) else: fixup.setInput(0, self._node) try: # Throws exception on render failure if (self.isBackgrounded()): nuke.executeBackgroundNuke( nuke.EXE_PATH, [write], nuke.FrameRanges(self._frameRange.value().split(',')), self._selectedViews(), self._getBackgroundLimits(), self._continueOnError.value(), self._flipbookEnum.value(), self._getOptions(write)) else: nuke.executeMultiple( (write, ), nuke.FrameRanges(self._frameRange.value().split(',')), self._selectedViews(), self._continueOnError.value()) except RuntimeError, msg: if msg.args[0][0:9] == "Cancelled": splitMsg = string.split(msg.args[0]) msg = """Render did not complete, do you want to show the completed range? Frame range %s contains %s frames but only %s finished.""" % ( self._frameRange.value(), splitMsg[3], splitMsg[1]) if nuke.ask(msg) == False: nuke.delete(fixup) fixup = None else: nuke.delete(fixup) fixup = None nuke.message("Flipbook render failed:\n%s" % (msg.args[0], ))
def render_movie_in_nuke(self, path, output_path, width, height, first_frame, last_frame, version, name, color_space): """ Use Nuke to render a movie. This assumes we're running _inside_ Nuke. :param path: Path to the input frames for the movie :param output_path: Path to the output movie that will be rendered :param width: Width of the output movie :param height: Height of the output movie :param first_frame: Start frame for the output movie :param last_frame: End frame for the output movie :param version: Version number to use for the output movie slate and burn-in :param name: Name to use in the slate for the output movie :param color_space: Colorspace of the input frames """ output_node = None ctx = self.__app.context # create group where everything happens group = nuke.nodes.Group() # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=path.replace(os.sep, "/")) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) if color_space: read["colorspace"].setValue(color_space) # now create the slate/burnin node burn = nuke.nodePaste(self._burnin_nk) burn.setInput(0, read) # set the fonts for all text fields burn.node("top_left_text")["font"].setValue(self._font) burn.node("top_right_text")["font"].setValue(self._font) burn.node("bottom_left_text")["font"].setValue(self._font) burn.node("framecounter")["font"].setValue(self._font) burn.node("slate_info")["font"].setValue(self._font) # add the logo burn.node("logo")["file"].setValue(self._logo) # format the burnins version_padding_format = "%%0%dd" % self.__app.get_setting("version_number_padding") version_str = version_padding_format % version if ctx.task: version_label = "%s, v%s" % (ctx.task["name"], version_str) elif ctx.step: version_label = "%s, v%s" % (ctx.step["name"], version_str) else: version_label = "v%s" % version_str burn.node("top_left_text")["message"].setValue(ctx.project["name"]) burn.node("top_right_text")["message"].setValue(ctx.entity["name"]) burn.node("bottom_left_text")["message"].setValue(version_label) # and the slate slate_str = "Project: %s\n" % ctx.project["name"] slate_str += "%s: %s\n" % (ctx.entity["type"], ctx.entity["name"]) slate_str += "Name: %s\n" % name.capitalize() slate_str += "Version: %s\n" % version_str if ctx.task: slate_str += "Task: %s\n" % ctx.task["name"] elif ctx.step: slate_str += "Step: %s\n" % ctx.step["name"] slate_str += "Frames: %s - %s\n" % (first_frame, last_frame) burn.node("slate_info")["message"].setValue(slate_str) # create a scale node scale = self.__create_scale_node(width, height) scale.setInput(0, burn) # Create the output node output_node = self.__create_output_node(output_path) output_node.setInput(0, scale) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(output_path) self.__app.ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame-1, last_frame, 1],), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group)
def _render_movie_in_nuke(self, fields, path, output_path, width, height, first_frame, last_frame): """ Use Nuke to render a movie. This assumes we're running _inside_ Nuke. """ output_node = None # create group where everything happens group = nuke.nodes.Group() # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=path.replace(os.sep, "/")) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) # now create the slate/burnin node burn = nuke.nodePaste(self._burnin_nk) burn.setInput(0, read) # set the fonts for all text fields burn.node("top_left_text")["font"].setValue(self._font) burn.node("top_right_text")["font"].setValue(self._font) burn.node("bottom_left_text")["font"].setValue(self._font) burn.node("framecounter")["font"].setValue(self._font) burn.node("slate_info")["font"].setValue(self._font) # add the logo burn.node("logo")["file"].setValue(self._logo) # format the burnins version_padding_format = "%%0%dd" % self.get_setting( "version_number_padding") version_str = version_padding_format % fields.get("version", 0) if self.context.task: version = "%s, v%s" % (self.context.task["name"], version_str) elif self.context.step: version = "%s, v%s" % (self.context.step["name"], version_str) else: version = "v%s" % version_str burn.node("top_left_text")["message"].setValue( self.context.project["name"]) burn.node("top_right_text")["message"].setValue( self.context.entity["name"]) burn.node("bottom_left_text")["message"].setValue(version) # and the slate slate_str = "Project: %s\n" % self.context.project["name"] slate_str += "%s: %s\n" % (self.context.entity["type"], self.context.entity["name"]) slate_str += "Name: %s\n" % fields.get("name", "Unnamed").capitalize() slate_str += "Version: %s\n" % version_str if self.context.task: slate_str += "Task: %s\n" % self.context.task["name"] elif self.context.step: slate_str += "Step: %s\n" % self.context.step["name"] slate_str += "Frames: %s - %s\n" % (first_frame, last_frame) burn.node("slate_info")["message"].setValue(slate_str) # create a scale node scale = self._create_scale_node(width, height) scale.setInput(0, burn) # Create the output node output_node = self._create_output_node(output_path) output_node.setInput(0, scale) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(output_path) self.ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame - 1, last_frame, 1], ), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group)
def render_in_nuke(path_to_frames, path_to_movie, extra_write_node_mapping, width, height, first_frame, last_frame, version, name, color_space, app_settings, ctx, render_info, is_subprocess=False): """ Use Nuke to render a movie. This assumes we're running _inside_ Nuke. :param path_to_frames: Path to the input frames for the movie :param path_to_movie: Path to the output movie that will be rendered :param extra_write_node_mapping: Mapping of write nodes with their output paths that should be rendered, other than the movie write node :param width: Width of the output movie :param height: Height of the output movie :param first_frame: Start frame for the output movie :param last_frame: End frame for the output movie :param version: Version number to use for the output movie slate and burn-in :param name: Name to use in the slate for the output movie :param color_space: Colorspace of the input frames :param app_settings: Settings of the app like slate_logo, version padding etc. :param ctx: context object for which the render is supposed to run :param render_info: Burnin nuke file to be used as template, codec settings for the movie. :param is_subprocess: If it's subprocess or not :return: Status of the nuke script execution """ output_node = None try: root_node = nuke.root() if is_subprocess: # set Nuke root settings (since this is a subprocess with a fresh session) root_node["first_frame"].setValue(first_frame) root_node["last_frame"].setValue(last_frame) # create group where everything happens group = nuke.nodes.Group() # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=path_to_frames.replace(os.sep, "/")) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) if color_space: read["colorspace"].setValue(str(color_space)) if is_subprocess: # set root_format = res of read node read_format = read.format() read_format.add('READ_FORMAT') root_node.knob('format').setValue('READ_FORMAT') # now create the slate/burnin node burn = nuke.nodePaste(render_info.get('burnin_nk')) burn.setInput(0, read) font = render_info.get('slate_font') # set the fonts for all text fields # TODO: find by class instead of using node names burn.node("top_left_text")["font"].setValue(font) burn.node("top_right_text")["font"].setValue(font) burn.node("bottom_left_text")["font"].setValue(font) burn.node("framecounter")["font"].setValue(font) burn.node("slate_info")["font"].setValue(font) # add the logo logo = app_settings.get('slate_logo', '') if not os.path.isfile(logo): logo = '' burn.node("logo")["file"].setValue(logo) # format the burnins ver_num_pad = app_settings.get('version_number_padding', 4) version_padding_format = "%%0%dd" % ver_num_pad version_str = version_padding_format % version if ctx.task: version_label = "%s, v%s" % (ctx.task["name"], version_str) elif ctx.step: version_label = "%s, v%s" % (ctx.step["name"], version_str) else: version_label = "v%s" % version_str # TODO: use context names instead positional so that the nodes can be moved around burn.node("top_left_text")["message"].setValue(ctx.project["name"]) if ctx.entity: burn.node("top_right_text")["message"].setValue( ctx.entity["name"]) burn.node("bottom_left_text")["message"].setValue(version_label) # and the slate slate_str = "Project: %s\n" % ctx.project["name"] if ctx.entity: slate_str += "%s: %s\n" % (ctx.entity["type"], ctx.entity["name"]) slate_str += "Name: %s\n" % name.capitalize() slate_str += "Version: %s\n" % version_str if ctx.task: slate_str += "Task: %s\n" % ctx.task["name"] elif ctx.step: slate_str += "Step: %s\n" % ctx.step["name"] slate_str += "Frames: %s - %s\n" % (first_frame, last_frame) burn.node("slate_info")["message"].setValue(slate_str) # Create a scale node scale = __create_scale_node(width, height) scale.setInput(0, burn) # Create the output node output_node = __create_output_node( path_to_movie, render_info.get('codec_settings', {})) output_node.setInput(0, scale) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(path_to_movie) ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame - 1, last_frame, 1], ), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group) except: return { 'status': 'ERROR', 'error_msg': '{0}'.format(traceback.format_exc()), 'output_path': path_to_movie } return {'status': 'OK'}
if len(views_input) > 1: flipbookFileNameTemp = "nuke_tmp_flip.%04d.%V.rgb" else: flipbookFileNameTemp = "nuke_tmp_flip.%04d.rgb" flipbooktmp = os.path.join(flipbooktmp, flipbookFileNameTemp) if nuke.env['WIN32']: flipbooktmp = re.sub("\\\\", "/", str(flipbooktmp)) fieldname = "file" if proxy: fieldname = "proxy" write = nuke.createNode("Write", fieldname + " {" + flipbooktmp + "} " + "tile_color 0xff000000", inpanel=False) #If called on a Viewer connect Write node to the one immediately above if exists. input = node if node.Class() == "Viewer": input = node.input(int(nuke.knob(node.name() + ".input_number"))) write.setInput(0, input) try: # Throws exception on render failure nuke.executeMultiple((write, ), ([start, end, incr], ), views_input) command(write, start, end, incr, views_input) except Exception, msg: nuke.message("Flipbook render failed:\n%s" % (msg, )) nuke.delete(write)
def _render(self, group_node, mov_path, png_path): """ Renders quickdaily node """ # setup quicktime output resolution width = self.get_setting("width", 1024) height = self.get_setting("height", 540) mov_reformat_node = group_node.node("mov_reformat") mov_reformat_node["box_width"].setValue(width) mov_reformat_node["box_height"].setValue(height) # setup output png path png_out = group_node.node("png_writer") png_path = png_path.replace(os.sep, "/") png_out["file"].setValue(png_path) # setup output quicktime path mov_out = group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # on the mac and windows, we use the quicktime codec # on linux, use ffmpeg # if sys.platform in ["win32","darwin"]: # # apple photo-jpeg movie # mov_out["file_type"].setValue('mov') # mov_out["codec"].setValue('apco') # mov_out["fps"].setValue(24) # #mov_out["settings"].setValue("000000000000000000000000000019a7365616e0000000100000001000000000000018676696465000000010000000e00000000000000227370746c0000000100000000000000006a706567000000000018000003ff000000207470726c000000010000000000000000000000000017f9db00000000000000246472617400000001000000000000000000000000000000530000010000000100000000156d70736f00000001000000000000000000000000186d66726100000001000000000000000000000000000000187073667200000001000000000000000000000000000000156266726100000001000000000000000000000000166d70657300000001000000000000000000000000002868617264000000010000000000000000000000000000000000000000000000000000000000000016656e647300000001000000000000000000000000001663666c67000000010000000000000000004400000018636d66720000000100000000000000006170706c00000014636c75740000000100000000000000000000001c766572730000000100000000000000000003001c00010000") # mov_out["mov32_pixel_format"].setValue('{{0} "default (YCbCrA 8-bit 444 Biased (r408))" "RGBA 8-bit" "YCbCrA 8-bit 444 Biased (r408)" "YCbCr 8-bit 422 (2vuy)"}') # mov_out["mov64_codec"].setValue("apco") # mov_out["mov64_bitrate"].setValue(20000) # mov_out["mov64_bitrate_tolerance"].setValue(40000000) # mov_out["mov64_quality_min"].setValue(2) # mov_out["mov64_quality_max"].setValue(31) # mov_out["mov64_gop_size"].setValue(12) # mov_out["mov64_b_frames"].setValue(0) # mov_out["checkHashOnRead"].setValue(False) # mov_out["selected"].setValue(True) # mov_out["xpos"].setValue(236) # mov_out["ypos"].setValue(-90) # elif sys.platform == "linux2": # mov_out["file_type"].setValue("ffmpeg") # mov_out["codec"].setValue("MOV format (mov)") # turn on the nodes mov_out.knob('disable').setValue(False) png_out.knob('disable').setValue(False) # finally render everything! # default to using the first view on stereo try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out, png_out], ([ self._get_first_frame()-1, self._get_last_frame(), 1 ],), [first_view] ) finally: # turn off the nodes again mov_out.knob('disable').setValue(True) png_out.knob('disable').setValue(True)
black_outside.setInput(0, last_node) last_node = black_outside if nuke_node_path: # wire in the undistort node tde_node["direction"].setValue("undistort" if mode == "und" else "distort") tde_node.setInput(0, last_node) last_node = tde_node # perform the pad reformat_full = nuke.nodes.Reformat(format=output_format.name(), resize="none") reformat_full.setInput(0, last_node) last_node = reformat_full # resize to new res # reformat_output = nuke.nodes.Reformat(format=output_format.name(), resize="width") # reformat_output.setInput(0, last_node) # last_node = reformat_output write_output = nuke.nodes.Write(file=output_path, name="write_output") write_output.setInput(0, last_node) # make sure the output dir exists if not os.path.exists(os.path.dirname(output_path)): os.makedirs(os.path.dirname(output_path)) if onlyDump: nuke.scriptSaveAs("/usr/tmp/dump.nk"); else: nuke.executeMultiple([write_output], [(first, last, 1)])
file=outFile) writeNode['_jpeg_quality'].setValue(0.75) elif format == 'tif': writeNode = nuke.nodes.Write(name=seq + "WriteLutBurn", colorspace="linear", file_type="tiff", file=outFile) writeNode['datatype'].setValue('16 bit') else: writeNode = nuke.nodes.Write(name=seq + "WriteLutBurn", colorspace="linear", file_type="exr", file=outFile) writeNode['use_limit'].setValue(1) if format != 'exr': colorConvertNode = nuke.nodes.OCIOColorSpace(in_colorspace="Linear", out_colorspace="Lut") colorConvertNode.setInput(0, sequenceGroupNode) writeNode.setInput(0, colorConvertNode) else: writeNode.setInput(0, sequenceGroupNode) writeNode['views'].setValue('left') allWriteNode.append(writeNode) nuke.scriptSave(outDir + seq + '_contactSheet.nk') masterNukeFile = '/tmp/tmpContactSheet.nk' nuke.scriptSave(masterNukeFile) fRange = nuke.FrameRanges('1-1') nuke.executeMultiple(tuple(allWriteNode), fRange, ['left']) os.remove(masterNukeFile)
def _createIntermediateNode(self): """Create a write node to render out the current node so that output may be used for flipbooking.""" flipbooktmp = self._getIntermediatePath() fieldname = "file" if self._useProxy.value(): fieldname = "proxy" fixup = nuke.createNode("Group", "tile_color 0xff000000", inpanel=False) with fixup: fixup.setName("Flipbook") inputNode = nuke.createNode("Input", inpanel=False) shuffle = nuke.createNode("Shuffle", inpanel=False) shuffle.knob("in").setValue(self._channels.value()) write = nuke.createNode("Write", fieldname + " {" + flipbooktmp + "}", inpanel=False) write.knob('file_type').setValue(self._getIntermediateFileType()) write.knob('views').fromScript(" ".join(self._selectedViews())) if self._getIntermediateFileType() == "exr": write.knob('compression').setValue("B44") if self._burnInLUT.value(): lut = self._getLUT() if lut != "None": write.knob('colorspace').setValue(lut) outputNode = nuke.createNode("Output", inpanel=False) #If called on a Viewer connect fixup node to the one immediately above if exists. if self._node.Class() == "Viewer": fixup.setInput( 0, self._node.input( int(nuke.knob(self._node.fullName() + ".input_number")))) else: fixup.setInput(0, self._node) try: # Throws exception on render failure if (self.isBackgrounded()): nuke.executeBackgroundNuke( nuke.EXE_PATH, [write], nuke.FrameRanges(self._frameRange.value().split(',')), self._selectedViews(), self._getBackgroundLimits(), self._continueOnError.value(), self._flipbookEnum.value(), self._getOptions(write)) else: nuke.executeMultiple( (write, ), nuke.FrameRanges(self._frameRange.value().split(',')), self._selectedViews(), self._continueOnError.value()) except RuntimeError, msg: if msg.args[0][0:9] == "Cancelled": splitMsg = string.split(msg.args[0]) msg = """Render did not complete, do you want to show the completed range? Frame range %s contains %s frames but only %s finished.""" % ( self._frameRange.value(), splitMsg[3], splitMsg[1]) if nuke.ask(msg) == False: nuke.delete(fixup) fixup = None else: nuke.delete(fixup) fixup = None nuke.message("Flipbook render failed:\n%s" % (msg.args[0], ))
def render_movie_in_nuke(self, path, output_path, width, height, first_frame, last_frame, version, name, color_space): """ Use Nuke to render a movie. This assumes we're running _inside_ Nuke. :param path: Path to the input frames for the movie :param output_path: Path to the output movie that will be rendered :param width: Width of the output movie :param height: Height of the output movie :param first_frame: Start frame for the output movie :param last_frame: End frame for the output movie :param version: Version number to use for the output movie slate and burn-in :param name: Name to use in the slate for the output movie :param color_space: Colorspace of the input frames """ output_node = None ctx = self.__app.context metadata = {} metadata['slate/font'] = self._font metadata['burnin/font'] = self._font metadata['burnin/top_left'] = ctx.project["name"] metadata['burnin/top_right'] = ctx.entity["name"] metadata['burnin/bottom_right'] = "[format %04d [frame]]" metadata['slate/logo'] = self._logo # format the burnins version_padding_format = "%%0%dd" % self.__app.get_setting( "version_number_padding") version_str = version_padding_format % version if ctx.task: version_label = "%s, v%s" % (ctx.task["name"], version_str) elif ctx.step: version_label = "%s, v%s" % (ctx.step["name"], version_str) else: version_label = "v%s" % version_str metadata['burnin/bottom_left'] = version_label slate_str = "Project: %s\n" % ctx.project["name"] slate_str += "%s: %s\n" % (ctx.entity["type"], ctx.entity["name"]) slate_str += "Name: %s\n" % name.capitalize() slate_str += "Version: %s\n" % version_str if ctx.task: slate_str += "Task: %s\n" % ctx.task["name"] elif ctx.step: slate_str += "Step: %s\n" % ctx.step["name"] slate_str += "Frames: %s - %s\n" % (first_frame, last_frame) metadata['slate/info'] = slate_str # create group where everything happens group = nuke.nodes.Group() # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=path.replace(os.sep, "/")) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) if color_space: read["colorspace"].setValue(color_space) # create a scale node scale = self.__create_scale_node(width, height) scale.setInput(0, read) # add the metadata to be used by the slate and burnin nodes mmd = self.__create_metadata_node(metadata) mmd.setInput(0, scale) # now create the slate and burnin nodes slate = nuke.nodePaste(self._slate_nk) slate.setInput(0, mmd) burn = nuke.nodePaste(self._burnin_nk) burn.setInput(0, mmd) switch = self.__create_switch_node(slate, burn) # Create the output node output_node = self.__create_output_node(output_path) output_node.setInput(0, switch) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(output_path) self.__app.ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame - 1, last_frame, 1], ), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group)
def _render(self, mov_path, start_frame, end_frame): """ Renders write node :param mov_path: temporary path where quicktime should be written :param int start_frame: First frame to render :param int end_frame: Last frame to render """ import nuke # setup quicktime output resolution (width, height) = self._bundle.execute_hook_method( "settings_hook", "get_resolution", base_class=self._bundle.base_hooks.ReviewSettings ) mov_reformat_node = self._group_node.node("mov_reformat") mov_reformat_node["box_width"].setValue(width) mov_reformat_node["box_height"].setValue(height) # setup output quicktime path mov_out = self._group_node.node("mov_writer") mov_path = mov_path.replace(os.sep, "/") mov_out["file"].setValue(mov_path) # apply the Write node codec settings we'll use for generating the Quicktime self._bundle.execute_hook_method( "settings_hook", "setup_quicktime_node", write_node=mov_out, base_class=self._bundle.base_hooks.ReviewSettings ) # turn on the node mov_out.knob("disable").setValue(False) # Disable slate based on UI settings. render_burnin = self.ui.burnin_groupbox.isChecked() burnin_username = self.ui.username_checkbox.isChecked() burnin_date = self.ui.date_checkbox.isChecked() burnin_shot = self.ui.shotinfo_checkbox.isChecked() burnin_frames = self.ui.frames_checkbox.isChecked() self._group_node.node("top_right_text")['disable'].setValue(not (render_burnin and burnin_date)) self._group_node.node("top_left_text")['disable'].setValue(not (render_burnin and burnin_shot)) self._group_node.node("bottom_left_text")['disable'].setValue(not (render_burnin and burnin_username)) self._group_node.node("framecounter")['disable'].setValue(not (render_burnin and burnin_frames)) if render_burnin: # update font according to options text_nodes = ["top_right_text", "top_left_text", "bottom_left_text", "framecounter"] for text_node in text_nodes: self._group_node.node(text_node).knob("color").setValue(1 if self.ui.fontcolor_combobox.currentIndex() == 0 else 0) self._group_node.node(text_node).knob("size").setValue(self.ui.fontsize_spinbox.value()) # render everything - default to using the first view on stereo logger.debug("Rendering quicktime") try: first_view = nuke.views()[0] nuke.executeMultiple( [mov_out], ([start_frame - 1, end_frame, 1],), [first_view] ) finally: # turn off the nodes again mov_out.knob("disable").setValue(True)
def render( self, input_path, output_path, width, height, first_frame, last_frame, version, name, color_space, ): """ Use Nuke to render a movie. :param str input_path: Path to the input frames for the movie :param str output_path: Path to the output movie that will be rendered :param int width: Width of the output movie :param int height: Height of the output movie :param int first_frame: The first frame of the sequence of frames. :param int last_frame: The last frame of the sequence of frames. :param str version: Version number to use for the output movie slate and burn-in :param str name: Name to use in the slate for the output movie :param str color_space: Colorspace of the input frames :returns: Location of the rendered media :rtype: str """ output_node = None ctx = self.__app.context # create group where everything happens group = nuke.nodes.Group() company_name = "NFA" project_name = ctx.project["name"] # getting current time today = datetime.date.today() date_formatted = time.strftime("%d/%m/%Y %H:%M") # getting filename current_scene_path = nuke.root().name() current_scene_path = current_scene_path.replace("/", os.path.sep) # get just filename current_scene_name = os.path.basename(current_scene_path) # drop .nk current_scene_name = os.path.splitext(current_scene_name)[0] file_name = current_scene_name.lower() user_data = sgtk.util.get_current_user(self.parent.sgtk) if user_data is None: user_name = "Unknown User" else: user_name = user_data.get("name", "Unknown User") # now operate inside this group group.begin() try: # create read node read = nuke.nodes.Read(name="source", file=input_path.replace(os.sep, "/")) read["on_error"].setValue("black") read["first"].setValue(first_frame) read["last"].setValue(last_frame) if color_space: read["colorspace"].setValue(color_space) # now create the slate/burnin node burn = nuke.nodePaste(self._burnin_nk) burn.setInput(0, read) # set the fonts for all text fields (disabled, uses standard arial in windows) #burn.node("top_left_text")["font"].setValue(self._font) #burn.node("top_right_text")["font"].setValue(self._font) #burn.node("bottom_left_text")["font"].setValue(self._font) #burn.node("framecounter")["font"].setValue(self._font) #burn.node("slate_info")["font"].setValue(self._font) # add the logo (added logo as roto node in nk file) #burn.node("logo")["file"].setValue(self._logo) # format the burnins version_padding_format = "%%0%dd" % self.__app.get_setting( "version_number_padding") version_str = version_padding_format % version if ctx.task: version_label = "%s, v%s" % (ctx.task["name"], version_str) elif ctx.step: version_label = "%s, v%s" % (ctx.step["name"], version_str) else: version_label = "v%s" % version_str burn.node("top_left_text")["message"].setValue(company_name) burn.node("top_right_text")["message"].setValue(date_formatted) burn.node("bottom_left_text")["message"].setValue(file_name) burn.node("bottom_center_text")["message"].setValue(project_name) # slate project info burn.node("slate_projectinfo")["message"].setValue(project_name) slate_str = "%s\n" % file_name slate_str += "%s - %s\n" % (first_frame, last_frame) slate_str += "%s\n" % date_formatted slate_str += "%s\n" % user_name slate_str += "v%s\n \n" % version_str fps = "[value root.fps]" slate_str += "%s\n" % fps resolution = "[value parent.input.width] x [value parent.input.height]" slate_str += "%s\n" % resolution burn.node("slate_info")["message"].setValue(slate_str) # create a scale node (disabled because we want the original resolution) #scale = self.__create_scale_node(width, height) #scale.setInput(0, burn) # Create the output node output_node = self.__create_output_node(output_path) output_node.setInput(0, burn) finally: group.end() if output_node: # Make sure the output folder exists output_folder = os.path.dirname(output_path) self.__app.ensure_folder_exists(output_folder) # Render the outputs, first view only nuke.executeMultiple([output_node], ([first_frame - 1, last_frame, 1], ), [nuke.views()[0]]) # Cleanup after ourselves nuke.delete(group) return output_path