from __future__ import print_function import os import os.path from os.path import abspath import nuke import KEnv import re from imp import reload from collections import OrderedDict # import ftrack_tools -> in getframerange(node) # martin@keller.io __version__ = '1.2' # default interface values projectDef = 'GEN' seasonDef = '01' episodeDef = '101' listTasks = ['taskOne___', 'taskTwo___'] listDepts = ['departmentOne___', 'departmentTwo___'] seqDef = '' shotDef = '' major_version = 1 minor_version = 1 user = 'xy' info = '' start = 1001 cutIn = 1001 cutOut = 1001 end = 1001 comment = '' # switches # generic project folder: //hades/p/_projekte/GENFOLDER GENFOLDER = 'GEN' INIT_DONE = False DEBUG = True UPDATE_TOOLSET = False WRITENODE_VERSION = 1.0 USE_ENV_PROJECT_ROOT = 1 WRITENODE_LABEL = 'exr compression: [value compression]' KELLERTABKNOBS = ( 'extension', 'ext', 'ver', 'explore', 'divider3', 'playinrv', 'pushtorv', 'pushtorvappend', 'divider2', 'ignore', 'divider1', 'set', 'info', 'element', 'subtask', 'task', 'w_reload', 'useshotenv', 'keller') # globals sequenceGlobal='' shotGlobal='' # Plugin / commands class sceneControl(KellerNukePlugin): def configurePlugin(self): self.menu = nuke.menu('Nuke') m = self.menu.addMenu('SceneControl') m.addCommand('SceneControl', 'import sceneControl; sceneControl.createSceneControl()',shortcut='F12') m.addCommand('Increment Major', 'import sceneControl; sceneControl.increment_major_version()', tooltip='Increment Major version and save script.', shortcut='alt+shift+s') m.addCommand('Increment Minor', 'import sceneControl; sceneControl.increment_minor_version()', tooltip='Increment Minor version and save script.', shortcut='alt+s') m.addCommand('Reload Config', 'import sceneControl; sceneControl.kenvDelete()') m.addCommand('Helpers/Read/Set Missing Frames Mode', 'import sceneControl; sceneControl.setErrorMode()', tooltip='Sets the Error Mode on selected Read nodes.') m.addCommand('Helpers/Read/Set colorspace on Nodes', 'import sceneControl; sceneControl.setOcioRole()', tooltip='Sets the OCIO role on selected Read / Write nodes.') m.addCommand('Helpers/Read/Reload Reads', 'import sceneControl; sceneControl.refresh_read_nodes()', tooltip='Reload footage of selected Read / Write nodes.') # m.addCommand('Helpers/Write/Ignore selected Nodes', 'import sceneControl; sceneControl.setIgnoreFlag(True)') m.addCommand('Helpers/Write/Manage selected Nodes','import sceneControl; sceneControl.setIgnoreFlag(False)') m.addCommand('Helpers/Write/Set colorspace on Nodes', 'import sceneControl; sceneControl.setOcioRole()', tooltip='Sets the OCIO role on selected Read / Write nodes.') m.addCommand('Helpers/Write/Update Write Nodes Tab', 'import sceneControl; sceneControl.updateWriteNodeConfig()', tooltip='Updates Keller Tab and functions of selected write nodes.') m.addCommand('Helpers/Write/Remove Write Nodes Tab', 'import sceneControl; sceneControl.removeKellerTab()', tooltip='Removes Keller Tab on selected Write Nodes.') #internal m.addCommand('Debug/Enable Debug Mode', 'import sceneControl; sceneControl.setDebug(True)') m.addCommand('Debug/Disable Debug Mode', 'import sceneControl; sceneControl.setDebug(False)') m.addCommand('Debug/DeleteKEnv', 'import sceneControl; sceneControl.kenvDelete()') m.addCommand('Debug/Internal/ReloadTasks', 'import sceneControl; sceneControl.kenvReloadTasks()', index=10) #m.addCommand('Debug/Internal/GetRenderpath', 'import sceneControl; sceneControl.kenvGetRenderpath(task,element)', index=11) #m.addCommand('Debug/Internal/GetPreviewOutput', 'import sceneControl; sceneControl.kenvGetPreviewOutput()', index=12) m.addCommand('Debug/Internal/WriteNodeSetPath', 'import sceneControl; sceneControl.kenvWriteSetPath(writeNode)', index=13) m.addCommand('Debug/Internal/WriteNodeReloadTasks', 'import sceneControl; sceneControl.kenvWriteReloadTasks(writeNode)', index=14) m.addCommand('Debug/Internal/KEnvQuery', 'import sceneControl; sceneControl.kenvQuery(query,**kwargs)', index=15) # TODO: add command to delete keller tab. # TODO: remove the commands from the menu #m.findItem('Draw/ReloadTasks').setVisible(False) #m.findItem('Draw/GetRenderpath').setVisible(False) #m.findItem('Draw/WriteNodeSetPath').setVisible(False) #m.findItem('Draw/WriteNodeReloadTasks').setVisible(False) # nuke.addOnCreate(onCreateWrite, nodeClass=('Write')) nuke.addOnScriptLoad(onScriptLoad) nuke.addKnobChanged(onKnobChanged) nuke.addOnDestroy(onDestroy) def unconfigurePlugin(self): self.menu.removeItem('SceneControl') self.menu.removeItem('Increment Major') self.menu.removeItem('Increment Minor') self.menu.removeItem('Reload Config') self.menu.removeItem('Helpers/Read/Set Missing Frames Mode') self.menu.removeItem('Helpers/Read/Set colorspace on Nodes') self.menu.removeItem('Helpers/Read/Reload Reads') self.menu.removeItem('Helpers/Write/Ignore selected Nodes') self.menu.removeItem('Helpers/Write/Manage selected Nodes') self.menu.removeItem('Helpers/Write/Set colorspace on Nodes') self.menu.removeItem('Helpers/Write/Update Write Nodes Tab') self.menu.removeItem('Helpers/Write/Remove Write Nodes Tab') # self.menu.removeItem('Debug/Enable Debug Mode') self.menu.removeItem('Debug/Disable Debug Mode') self.menu.removeItem('Debug/DeleteKEnv') self.menu.removeItem('Debug/Internal/ReloadTasks') #self.menu.removeItem('Debug/Internal/GetRenderpath') #self.menu.removeItem('Debug/Internal/GetPreviewOutput') self.menu.removeItem('Debug/Internal/WriteNodeSetPath') self.menu.removeItem('Debug/Internal/WriteNodeReloadTasks') self.menu.removeItem('Debug/Internal/KEnvQuery') # nuke.removeOnCreate(onCreateWrite) nuke.removeOnScriptLoad(onScriptLoad) nuke.removeKnobChanged(onKnobChanged) nuke.removeOnDestroy(onDestroy) # EVENTS def onScriptLoad(): sc = getSceneControl() if sc is None: createSceneControl() else: # SceneControl in script if kenvModuleLoaded(): print('SceneControl: Info. Script Load. Generating KEnv environment...') initSceneControlValues(sc) # init shot set_shot() def onKnobChanged(): # sceneControl ready k = nuke.thisKnob() refresh = ['project','dept','task','element','sequence','shot','major_version','minor_version','info','user','useEnvProjectRoot'] task_refresh = ['dept','task'] exr_compression = ['compression',] if k.name() in task_refresh: print('SceneControl: Info. Event task_refresh triggered.') # Department changed, loading new tasks kenvReloadTasks() if k.name() in refresh: print('SceneControl: Info. Event refresh triggered.') # Config changed, loading new tasks kenvGetWorkFile() pass # exr compression on write nodes if k.name() in exr_compression: # get the node n = nuke.thisNode() if k.value().startswith('Zip'): # % (r * 255, g * 255, b * 255, 1), 16): change r g and b to your liking hexColour = int('%02x%02x%02x%02x' % (184, 184, 0, 1), 16) n['tile_color'].setValue(hexColour) if k.value().startswith('DW'): # % (r * 255, g * 255, b * 255, 1), 16): change r g and b to your liking hexColour = int('%02x%02x%02x%02x' % (1 * 255, 0.666 * 255, 0.266 * 255, 1), 16) n['tile_color'].setValue(hexColour) def onCreateWrite(): n = nuke.thisNode() createCustomWrite(n) return def onDestroy(): print('SceneControl: Info. Nice meeting you. Removing Kenv now...') try: del(nuke.kenv) except: print('SceneControl: Info. KEnv was already gone.') # SceneControl def getSceneControl(): c = nuke.exists('sceneCtrl') if c: sc = nuke.toNode('sceneCtrl') else: print('SceneControl: Error. No SceneControl node found. Creating one for you.') import sceneControl deselectAll() sceneControl.createSceneControl() sc = nuke.toNode('sceneCtrl') return sc def createSceneControl(): # deselect all nodes deselectAll() # createUI print('SceneControl: Info. Creating SceneControl at Nuke root level.') #with nuke.root(): # for calling from within groups try: nuke.thisParent().begin() except: pass scenecontrol = createSceneControlUI() # fill out kenvLoaded = kenvModuleLoaded() if kenvLoaded is not None: initSceneControlValues(scenecontrol) pass else: pass sc = nuke.toNode('sceneCtrl') # Init done. Callbacks now armed. global INIT_DONE INIT_DONE = True # touch sc.knobs()['major_version'].setValue(0) sc.knobs()['major_version'].setValue(1) try: nuke.thisParent().end() except: pass return sc def createSceneControlUI(): n = nuke.Node('NoOp') n.setName('sceneCtrl') n['hide_input'].setValue(True) # % (r * 255, g * 255, b * 255, 1), 16): change r g and b to your liking hexColour = int('%02x%02x%02x%02x' % (0.2 * 255, 0.478 * 255, 0.647 * 255, 1), 16) n['tile_color'].setValue(hexColour) n['label'].setValue('_\n__') # ########################### # --------------------------- # tab main # --------------------------- # ########################### k = nuke.Tab_Knob('main', 'Main') n.addKnob(k) # Project k = nuke.String_Knob('project', 'Project') k.setTooltip('Project Shortname') n.addKnob(k) n.knob('project').setValue(projectDef) n.knob('project').setFlag(nuke.STARTLINE) # Department k = nuke.Enumeration_Knob('dept', 'Dept', listDepts) k.setTooltip('Department. Changes tasks and servers.') n.addKnob(k) n.knob('dept').clearFlag(nuke.STARTLINE) # Task k = nuke.Enumeration_Knob('task', 'Task', listTasks) n.addKnob(k) n.knob('task').clearFlag(nuke.STARTLINE) k = nuke.String_Knob('element', 'Element') k.setTooltip('Optional Element.') n.addKnob(k) n.knob('element').setValue('') n.knob('element').clearFlag(nuke.STARTLINE) # Update from KEnv k = nuke.PyScript_Knob('reloadConfig', 'Reload', 'sceneControl.kenvDelete()') k.setTooltip('Reload project config file.') n.addKnob(k) # Season k = nuke.String_Knob('season', 'Season') n.addKnob(k) n.knob('season').setValue(seasonDef) n.knob('season').setVisible(False) # Episode k = nuke.String_Knob('episode', 'Episode') n.addKnob(k) n.knob('episode').setValue(episodeDef) n.knob('episode').setVisible(False) # _______________________________________________________________ k = nuke.Text_Knob('divider1', '') n.addKnob(k) # _______________________________________________________________ # Sequence k = nuke.String_Knob('sequence', 'Seq') k.setTooltip( 'can be a sequence number or gen when doing generic tasks.\n\ncomp_001_010.comp_v01.ms.nk\ncomp_gen.footageIngest_v01.ms.nk') n.addKnob(k) n.knob('sequence').setValue(seqDef) # Shot k = nuke.String_Knob('shot', 'Shot') k.setTooltip( 'can be a shot number or gen in a multiShot context.\n\ncomp_001_010.comp_v01.ms.nk\ncomp_001_gen.comp_v01.ms.nk') n.addKnob(k) n.knob('shot').setValue(shotDef) n.knob('shot').clearFlag(nuke.STARTLINE) # Major Version k = nuke.Int_Knob('major_version', 'Major') n.addKnob(k) k.setTooltip('Increment Major Version and save script') n.knob('major_version').setValue(major_version) k = nuke.PyScript_Knob('increment_major_version', '+', 'sceneControl.increment_major_version()') n.addKnob(k) # Minor Version k = nuke.Int_Knob('minor_version', 'Minor') n.addKnob(k) k.setTooltip('Increment Minor Version and save script') n.knob('minor_version').setValue(minor_version) n.knob('minor_version').clearFlag(nuke.STARTLINE) k = nuke.PyScript_Knob('increment_minor_version', '+', 'sceneControl.increment_minor_version()') n.addKnob(k) # Save k = nuke.PyScript_Knob('save_script', 'Save', 'sceneControl.save_script()') k.setTooltip('Save Script with current Major and Minor') n.addKnob(k) # Overwrite k = nuke.Boolean_Knob('overwrite', 'Overwrite') k.setTooltip('Automatically overwrite Scriptfiles without asking.') n.addKnob(k) n.knob('overwrite').setValue(0) n.knob('overwrite').setVisible(True) # Info / Comment k = nuke.String_Knob('info', 'Info') k.setTooltip('Additional (mandatory) File Info.') n.addKnob(k) n.knob('info').setValue(info) # User Short k = nuke.String_Knob('user', 'User') n.addKnob(k) k.setTooltip('User Short. Reading Env Variable: USER_SHORT') n.knob('user').setValue(user) n.knob('user').clearFlag(nuke.STARTLINE) # Divider _______________________________________________________________ k = nuke.Text_Knob('divider2', '') n.addKnob(k) # _______________________________________________________________ # Foldername preview k = nuke.String_Knob('folder', 'Folder') n.addKnob(k) n.knob('folder').setValue('') n.knob('folder').setEnabled(False) k.setTooltip('Save folder Preview.') # Foldername preview k = nuke.Boolean_Knob('useEnvProjectRoot', 'Use Env Project Root') n.addKnob(k) n.knob('useEnvProjectRoot').setValue(USE_ENV_PROJECT_ROOT) k.setTooltip('Use env variables for 2d and 3d servers set in the site_config.\nUse these env variables before nuke startup.') n.knob('useEnvProjectRoot').clearFlag(nuke.STARTLINE) # Filename preview k = nuke.String_Knob('file', 'File') n.addKnob(k) n.knob('file').setValue('') n.knob('file').setEnabled(False) k.setTooltip('Save file Preview.') # Divider _______________________________________________________________ k = nuke.Text_Knob('divider3', '') n.addKnob(k) # _______________________________________________________________ # FrameStart k = nuke.Int_Knob('fStart', 'Start') n.addKnob(k) k.setTooltip('Startframe') n.knob('fStart').setValue(start) # FrameCutIn k = nuke.Int_Knob('fCutIn', 'CutIn') n.addKnob(k) k.setTooltip('CutIn') n.knob('fCutIn').setValue(cutIn) n.knob('fCutIn').clearFlag(nuke.STARTLINE) # FrameCutOut k = nuke.Int_Knob('fCutOut', 'CutOut') n.addKnob(k) k.setTooltip('CutOut') n.knob('fCutOut').setValue(cutOut) n.knob('fCutOut').clearFlag(nuke.STARTLINE) # FrameEnd k = nuke.Int_Knob('fEnd', 'End') n.addKnob(k) k.setTooltip('Endframe') n.knob('fEnd').setValue(end) n.knob('fEnd').clearFlag(nuke.STARTLINE) # Button Get Framerange (ftrack) k = nuke.PyScript_Knob('get_framerange', 'Get Range', 'sceneControl.get_framerange(nuke.thisNode())') n.addKnob(k) n.knob('get_framerange').setTooltip('Get Framerange from FTrack.\nPlease check you firewall rules and and allow ftrack ip 104.155.3.128 on port 443') # Button Set Framerange k = nuke.PyScript_Knob('set_framerange', 'Set Range', 'sceneControl.set_framerange(nuke.thisNode())') n.addKnob(k) n.knob('set_framerange').setTooltip('Set Framerange from SceneControl Interface') n.knob('set_framerange').clearFlag(nuke.STARTLINE) # Comment k = nuke.Multiline_Eval_String_Knob('comment', 'Comment') n.addKnob(k) n.knob('comment').setValue(comment) # Update / publish if UPDATE_TOOLSET: # Button update Layer k = nuke.PyScript_Knob('update_layer', 'Update Layer', 'sceneControl.update_layer()') n.addKnob(k) n.knob('update_layer').setFlag(nuke.STARTLINE) # Button connect all Layers k = nuke.PyScript_Knob('autoconnect_layers', 'Connect Layers', 'sceneControl.autoconnect_layers(nuke.thisNode())') n.addKnob(k) n.knob('autoconnect_layers').setFlag(nuke.STARTLINE) # Button remove all layers k = nuke.PyScript_Knob('remove_all_layers', 'Remove All Layers', 'sceneControl.remove_all_layers(nuke.thisNode())') n.addKnob(k) n.knob('remove_all_layers').setTooltip('Removes all Layers in SceneControl.') # Button delete all reads k = nuke.PyScript_Knob('remove_scnctrl_reads', 'Delete All Reads', 'sceneControl.remove_scnctrl_reads(nuke.thisNode())') n.addKnob(k) n.knob('remove_scnctrl_reads').setTooltip('Deletes all reads created by SceneControl.') n.knob('remove_scnctrl_reads').setFlag(nuke.STARTLINE) n.knob('remove_scnctrl_reads').setVisible(False) # Button publish Shot k = nuke.PyScript_Knob('publish_shot', 'Publish', 'sceneControl.publish_shot()') n.addKnob(k) n.knob('publish_shot').setFlag(nuke.STARTLINE) # invisible helpers # helper k = nuke.Int_Knob('layerNum', 'Slots') n.addKnob(k) n.knob('layerNum').setValue(0) n.knob('layerNum').setVisible(False) # used for resolving expressions k = nuke.EvalString_Knob('eval_helper', 'eval_helper') n.addKnob(k) n.knob('eval_helper').setValue('') n.knob('eval_helper').setVisible(False) # for debug disable above k = nuke.Boolean_Knob('stereoToggle', 'Stereo Toggle') n.addKnob(k) n.knob('stereoToggle').setValue(0) n.knob('stereoToggle').setVisible(False) # used for resolving expressions k = nuke.EvalString_Knob('precomp_output', 'Precomp Output') n.addKnob(k) n.knob('precomp_output').setValue('') n.knob('precomp_output').setVisible(False) # for debug disable above k = nuke.Boolean_Knob('debug', 'Debug') n.addKnob(k) n.knob('debug').setValue(1) n.knob('debug').setVisible(False) # end helper # return sceneControl Object sc = nuke.toNode(n.name()) return sc def initSceneControlValues(sceneControl): if sceneControl is not None: k = sceneControl.knobs() # debug k['debug'].setValue(DEBUG) proj = checkEnvEntry('PROJECT') if proj is None: proj = GENFOLDER kenvReloadTasks() proj = checkEnvEntry('PROJECT') k['project'].setValue(proj) try: k['user'].setValue(checkEnvEntry('USER_SHORT')) except: print('SceneControl: Warning. Please enter your shortname.') # export Sequence and Shot Environment variables exportEnv() # KEnv functions def kenvCheck(): try: nuke.kenv except: kenvCreate() print('SceneControl: Info. Creating kenv.') def kenvModuleLoaded(): from imp import reload try: import KEnv reload(KEnv) except: print('SceneControl: Error. No KEnv module found') return False return KEnv def kenvCreate(): try: project = os.environ['PROJECT'] except: project = GENFOLDER # KEnv env = KEnv.create(PROJECT=project, APP_ID='nuke') # save KEnv to Nuke to access if by other nodes / tools nuke.kenv = env def kenvDelete(): try: del(nuke.kenv) print('SceneControl: Info. Deleting nuke.kenv.') except: print('SceneControl: Info. nuke.kenv not found.') def kenvReloadTasks(): sceneControl = getSceneControl() k = sceneControl.knobs() kenvCheck() # KEnv query dept = nuke.kenv.get('DEPARTMENTS') k['dept'].setValues(dept) tasks = nuke.kenv.get('TASKS', DEPT=k['dept'].value(), APP_ID='nuke') k['task'].setValues(tasks) return tasks def kenvGetWriteOutput(writeTask, writeElement, writeInfo, ext): sceneControl = getSceneControl() k = sceneControl.knobs() kenvCheck() # debug if k['debug'].getValue(): print(('SceneControl: Debug. WriteTask: %s, WriteElement: %s, WriteInfo: %s') % (writeTask, writeElement, writeInfo)) # useEnvProjectRoot useEnv = k['useEnvProjectRoot'].value() if writeElement == '': writeElement = None if writeInfo == '': writeInfo = None if writeTask.lower() == 'scripttask': # get task from sceneControl and not from the write node # sceneControl task task = k['task'].value() writeTask = task # KEnv query renderpath = kenvQuery('RENDER_2D_FILE', element=writeElement, task=writeTask, minor_version=None, info=writeInfo, ext=ext, USE_ENV_PROJECTROOT=useEnv) else: # KEnv query renderpath = kenvQuery('PRECOMP_FILE', element=writeElement, task=writeTask, minor_version=None, info=writeInfo, ext=ext, USE_ENV_PROJECTROOT=useEnv) return renderpath def kenvGetWorkFile(): sceneControl = getSceneControl() k = sceneControl.knobs() kenvCheck() info = k['info'].value() if info == '': info = None element = k['element'].value() if element == '': element = None # KEnv query script = kenvQuery('WORK_FILE', element=element, info=info) dir = kenvQuery('WORK_DIR', element=element, info=info) try: k['folder'].setValue(dir+'/') except: print(('SceneControl: Error. Error setting directory: %s') % dir) try: k['file'].setValue(script.split('/')[-1]) except: print(('SceneControl: Error. Error setting file: %s') % script) # main Kenv Query def kenvQuery(query , **kwargs): # sceneControl sceneControl = getSceneControl() k = sceneControl.knobs() kenvCheck() # sceneControl values: debug = k['debug'].getValue() project = k['project'].value() dept = k['dept'].value() sequence = k['sequence'].value() shot = k['shot'].value() element = k['element'].value() task = k['task'].value() major_version = int(k['major_version'].value()) minor_version = int(k['minor_version'].value()) user = k['user'].value() info = k['info'].value() ext = 'exr' app_id = 'nuke' # useEnvProjectRoot useEnv = k['useEnvProjectRoot'].value() # read out kwargs for k,v in kwargs.items(): if k == 'project': project = v if k == 'dept': dept = v if k == 'sequence': sequence = v if k == 'shot': shot = v if k == 'element': element = v if k == 'task': task = v if k == 'major_version': major_version = v if k == 'minor_version': minor_version = v if k == 'user': user = v if k == 'info': info = v if k == 'ext': ext = v if k == 'app_id': app_id = v if k == 'useEnv': useEnv = v # info infostr='' if info == '': info = None infostr = 'None' # element elementstr='' if element == '': element = None elementstr = 'None' # debug if debug: print('SceneControl: Debug kenv query:') print('PROJECT: ' + project) print('SHOT: ' + shot) print('SEQUENCE: ' + sequence) print('DEPT: ' + dept) print('TASK: ' + task) print('MAJOR_VERSION: ' + str(int(major_version))) if minor_version is None: print('MINOR_VERSION: ' + 'None') else: print('MINOR_VERSION: ' + str(int(minor_version))) print('ELEMENT: ' + elementstr) print('INFO: ' + infostr) print('USER_SHORT: ' + user) print('EXT: ' + ext) print('APP_ID: ' + app_id) # KEnv if minor_version is None: result = nuke.kenv.get(query, PROJECT=project, DEPT=dept, SEQUENCE=sequence, SHOT=shot, ELEMENT=element, TASK=task, MAJOR_VERSION=int(major_version), INFO=info, EXT=ext, USER_SHORT=user, APP_ID=app_id, USE_ENV_PROJECTROOT=useEnv) else: result = nuke.kenv.get(query, PROJECT=project, DEPT=dept, SEQUENCE=sequence, SHOT=shot, ELEMENT=element, TASK=task, MAJOR_VERSION=int(major_version), MINOR_VERSION=int(minor_version), INFO=info, EXT=ext, USER_SHORT=user, APP_ID=app_id, USE_ENV_PROJECTROOT=useEnv) if debug: print('SceneControl: Debug kenv query: ' + result) return result # called from write nodes def kenvWriteSetPath(n): print('Our_Write: Info. Setting output file path') sceneControl = getSceneControl() k = sceneControl.knobs() kenvCheck() #debug if k['debug'].getValue(): print(('SceneControl: Debug. Setting path on: %s') % n.name()) subtask = n.knob('subtask').value() if subtask is None: subtask = '' element = n.knob('element').value() if element == '': element = None info = n.knob('info').value() if info == '': info = None ext = n.knob('extension').value() # dummy file = '' file = kenvGetWriteOutput(subtask, element, info, ext) if file != '': try: n.knob('file').setValue(file) except: pass return def kenvWriteReloadSubTasks(n): sceneControl = getSceneControl() kenvCheck() # KEnv query tasks = nuke.kenv.get('SUBTASKS_2D') try: n.knob('subtask').setValues(tasks) except: pass return # helpers # todo: set selected Reads to framerange def setIgnoreFlag(state): s = nuke.selectedNodes() if len(s) == 0: nuke.message('Please select some Nodes first.') return for n in s: if n.Class() == 'Write' or n.Class() == 'DeepWrite': try: n.knobs()['ignore'].setValue(state) except: print(('SceneControl: Warning. Cannot find ignore flag on: %s') % n.name()) def setErrorMode(): n = nuke.selectedNodes() if len(n) == 0: nuke.message('Please select some Nodes first.') return w = nuke.nodes.Read() onerror = w['on_error'].values() # spaces in the names quoted = ['{%s}' % c for c in onerror] p = nuke.Panel('Missing Frames') p.addEnumerationPulldown('Missing Frames', ' '.join(quoted)) p.show() ret = p.value('Missing Frames') sel = nuke.selectedNodes() for s in sel: if s.Class() == 'Read' or s.Class() == 'DeepRead': s.knobs()['on_error'].setValue(ret) def setOcioRole(): n = nuke.selectedNodes() if len(n) == 0: nuke.message('No node(s) selected.') # create temporary write node w = nuke.nodes.Write(file_type='exr') colorspace = w['colorspace'].values() # delete write node nuke.delete(w) choice = [] for s in colorspace: if not s.startswith('Colorspaces/'): choice.append(s.split('\t')[0]) else: choice.append(s) # spaces in the names quoted = ['{%s}' % c for c in choice] # TODO: create cascading Enumeration pulldown. Not possible with panel? p = nuke.Panel('Colorspace') p.addEnumerationPulldown('Colorspace', ' '.join(quoted)) p.show() ret = p.value('Colorspace') if ret is not None: for s in n: if s.Class() == 'Read' or s.Class() == 'Write': s.knobs()['colorspace'].setValue(ret) def setDebug(state): sceneControl = getSceneControl() if sceneControl is None: print('SceneControl: Error. No SceneControl node found. Exiting.') return k = sceneControl.knobs() k['debug'].setValue(state) if state is False: print('SceneControl: Info. Set SceneControl Debug Mode to: False') else: print('SceneControl: Info. Set SceneControl Debug Mode to: True') def deselectAll(): for each in nuke.allNodes(): each.knob('selected').setValue(False) return def getFilename(): return nuke.Root()['name'].getValue() def find_node_by_type(nodename, nodeclass): nodes = nuke.allNodes() for n in nodes: if n.Class() == nodeclass: if n.knob('label').getValue().lower() == nodename.lower(): return n return None def updateWriteNodePaths(): nodes = nuke.allNodes() for n in nodes: if n.Class() == 'Write' or n.Class() == 'DeepWrite': try: if n.knobs()['ignore'].value() == True: print('SceneControl: Info. Found ignore flag on %s. Skipping.' % n.name()) else: try: print('SceneControl: Info. Setting output file on %s.' % n.name()) nuke.toNode(n.name()).knobs()['set'].execute() except: print('SceneControl: Error. Error setting output file on %s.' % n.name()) except: print ('SceneControl: Info. Skipping Node %s. Old Write Node. Consider creating a new one.' % n.name()) def updateWriteNodeConfig(): # TODO: more automated update function. import sceneControl # save these for reapplying later on saveKnobs = ('info', 'element', 'subtask', 'ignore') # get all reads nodes = [node for node in nuke.selectedNodes() if node.Class() == 'Write'] if len(nodes) >0: for n in nodes: knobs = n.knobs() # save config try: info = knobs['info'].value() element = knobs['element'].value() subtask = knobs['subtask'].value() ignore = knobs['ignore'].value() except: pass for c in KELLERTABKNOBS: try: n.removeKnob(knobs[c]) except: pass # create new Keller tab sceneControl.createCustomWrite(n) # refresh subtasks sceneControl.kenvWriteReloadSubTasks(n) # restore old values try: n.knobs()['info'].setValue(info) except: print('SceneControl: Error. Node %s. Cannot set value on knob: %s') % (n.name(), info) try: n.knobs()['element'].setValue(element) except: print('SceneControl: Error. Node %s. Cannot set value on knob: %s') % (n.name(), element) try: n.knobs()['subtask'].setValue(subtask) except: print('SceneControl: Error. Node %s. Cannot set value on knob: %s') % (n.name(), subtask) else: pass return def removeKellerTab(): # get all reads nodes = [node for node in nuke.selectedNodes() if node.Class() == 'Write'] if len(nodes) >0: for n in nodes: knobs = n.knobs() # save config try: info = knobs['info'].value() element = knobs['element'].value() subtask = knobs['subtask'].value() ignore = knobs['ignore'].value() except: pass for c in KELLERTABKNOBS: try: n.removeKnob(knobs[c]) except: pass else: pass return def refresh_read_nodes(): nodes = nuke.selectedNodes() if len(nodes)==0: nodes = nuke.allNodes() print('SceneControl: Info. No node selected. Reloading all reads.') for n in nodes: if n.Class() == 'Read' or n.Class() == 'DeepRead': try: nuke.toNode(n.name()).knobs()['reload'].execute() print('SceneControl: Info. Reloading %s.' % n.name()) except: pass def autoconnect_layers(node): n = nuke.thisNode() nu = n['layerNum'].getValue() num = int(nu) for i in range(1, num + 1): create_deepreadnode(i, autoconnect=True) create_readnode(i, autoconnect=True) return def checkEnvEntry(value): try: val = os.environ[value] except: print(('SceneControl: Info. Env variable %s not set.') %value) return None return val def exportEnv(): sceneControl = getSceneControl() k = sceneControl.knobs() project = k['project'].value() if project == '': project = 'None' # temp if project == 'HOTZ': project = 'HOT' sequence = k['sequence'].value() if sequence == '': sequence = 'None' shot = k['shot'].value() if shot == '': shot = 'None' os.environ['JOB'] = str(project) os.environ['PREFIX'] = str(project) # houdini world os.environ['SEQUENCE'] = str(sequence) os.environ['SEQ'] = str(sequence) # houdini world os.environ['SHOT'] = str(shot) print('SceneControl: Info. Exported Env Variables SEQUENCE: {0} and SHOT: {1}'.format(sequence,shot)) return def set_shot(): global sequenceGlobal global shotGlobal envExportNeeded = False sceneControl = getSceneControl() k = sceneControl.knobs() # sequence sequence = k['sequence'].value() if sequence != 'gen' and sequence !='': if sequence != sequenceGlobal: print('SceneControl: Info. Env Export needed') envExportNeeded = True # new sequence sequenceGlobal = sequence # shot shot = k['shot'].value() if shot != 'gen' and shot !='': if shot != shotGlobal: print('SceneControl: Info. Env Export needed') envExportNeeded = True # new sequence shotGlobal = shot # sequence and or shot changed if envExportNeeded: # export sequence and shot exportEnv() # refresh ocio config print('SceneControl: Info. Reloading ocio config.') try: v = nuke.ViewerProcess.node().knob('view').getValue() # reset viewer to default project viewerprocess nuke.ViewerProcess.node().knob('view').setValue(0) except: # empty script without viewer... pass # reload ocio config nuke.root().knobs()['reloadConfig'].execute() try: # set viewerProcess back nuke.ViewerProcess.node().knob('view').setValue(int(v)) except: # empty script without viewer... pass # write nodes def createCustomWrite(n): # Task ''' taskList = ('comp',) try: taskList = sceneControl.kenvReloadTasks() except: print('Our_Write: Error. Cannot call sceneControl.kenvReloadTasks()') pass ''' try: tab = n.knobs()['keller'].value() except: tab = None if tab is None: pass else: # already existing return # check element import sceneControl sceneControl = sceneControl.getSceneControl() element = sceneControl.knobs()['element'].value() # create tab print('Our_Write: Info. Creating KellerTab') k = nuke.Tab_Knob('keller', 'Keller') n.addKnob(k) exts = n.knobs()['file_type'].values() k = nuke.Enumeration_Knob('extension', 'Extension', exts) n.addKnob(k) n.knob('extension').setValue('exr') n.knob('extension').setFlag(nuke.STARTLINE) # task subTaskList = ('--------------->',) k = nuke.Enumeration_Knob('subtask', 'Subtask', subTaskList) k.setTooltip('Defaults to the Task selected in sceneControl, ignoring Element and Info.\nAll other subtasks are pre-renders and get rendered into the precomp (=prerender) directory.') n.addKnob(k) n.knob('subtask').setFlag(nuke.STARTLINE) # Reload k = nuke.PyScript_Knob('w_reload', 'Reload', 'sceneControl.kenvWriteReloadSubTasks(nuke.thisNode())') k.setTooltip('Reloads the subtasks. If the project_config.py was changed you need to re-init the config with the SceneControl button \'reload\'.') k.setTooltip('Reload Tasks') n.addKnob(k) # element k = nuke.String_Knob('element', 'Element') k.setTooltip('Optional Specifier. For example [BG]_denoise. [FG]_denoise.') n.addKnob(k) # if element is in sceneControl n.knob('element').setValue(element) # info k = nuke.String_Knob('info', 'Info') k.setTooltip('Optional Info before Framenumber.\nPRO_comp3d_001_010.comp3d_v008.[acescg].%04d.exr') n.addKnob(k) n.knob('info').setValue('') # set k = nuke.PyScript_Knob('set', 'Set', 'sceneControl.kenvWriteSetPath(nuke.thisNode())') k.setTooltip('Set Output Path of this node') n.addKnob(k) n.knob('set').setFlag(nuke.STARTLINE) # _______________________________________________________________ k = nuke.Text_Knob('divider1', '') n.addKnob(k) # _______________________________________________________________ # ignore k = nuke.Boolean_Knob('ignore', 'ignore in sceneControl') n.addKnob(k) n.knob('ignore').setTooltip('If enabled sceneControl will NOT change any configuration of this write node such as Filepath, Version etc.') n.knob('ignore').setValue(0) # _______________________________________________________________ k = nuke.Text_Knob('divider2', '') n.addKnob(k) # _______________________________________________________________ # play in new rv k = nuke.PyScript_Knob('playinrv', 'Play in RV', 'playInRV.playInRV(nuke.thisNode(),0)') n.addKnob(k) n.knob('playinrv').setTooltip('Opens new instance of RV') n.knob('playinrv').setFlag(nuke.STARTLINE) # push to rv k = nuke.PyScript_Knob('pushtorv', 'Push to RV', 'playInRV.playInRV(nuke.thisNode(),1)') n.addKnob(k) n.knob('pushtorv').setTooltip('Push to tagged RV. Will open RV and uses this instance to directly push sequences.') # push to rv / append k = nuke.PyScript_Knob('pushtorvappend', 'Push to RV (append)', 'playInRV.playInRV(nuke.thisNode(),2)') n.addKnob(k) n.knob('pushtorvappend').setTooltip('Push to RV and append to existing sources') n.knob("pushtorvappend").clearFlag(nuke.STARTLINE) k = nuke.Boolean_Knob("useshotenv", "use shot env") n.addKnob(k) n.knob("useshotenv").setTooltip("Use Sequence and Shot Env entries in order for RV to load shot specific configs.") n.knob("useshotenv").setValue(1) # _______________________________________________________________ k = nuke.Text_Knob("divider3", "") n.addKnob(k) # _______________________________________________________________ # explore k = nuke.PyScript_Knob("explore", "Explore", "exploreThis.exploreThis()") n.addKnob(k) n.knob("explore").setTooltip("Open Folder") # version k = nuke.Array_Knob("ver", "Version") n.addKnob(k) n.knob("ver").setValue(WRITENODE_VERSION) n.knob("ver").setVisible(False) # label if n.knob("label").value() != "": n.knob("label").setValue('\n' + WRITENODE_LABEL) else: n.knob("label").setValue(WRITENODE_LABEL) n.knob('file_type').setValue('exr') k = n.knob('compression') if k.value().startswith('Zip'): # % (r * 255, g * 255, b * 255, 1), 16): change r g and b to your liking hexColour = int('%02x%02x%02x%02x' % (184, 184, 0, 1), 16) n['tile_color'].setValue(hexColour) if k.value().startswith('DW'): # % (r * 255, g * 255, b * 255, 1), 16): change r g and b to your liking hexColour = int('%02x%02x%02x%02x' % (1 * 255, 0.666 * 255, 0.266 * 255, 1), 16) n['tile_color'].setValue(hexColour) # saving def save_script(): sceneControl = getSceneControl() k = sceneControl.knobs() # overwrite existing scene without notice? owrite = k['overwrite'].value() # info info = k['info'].value() if info == '': info = None # element element = k['element'].value() if element == '': element = None # useEnvProjectRoot useEnv = k['useEnvProjectRoot'].value() # KEnv Query script = kenvQuery('WORK_2D_SCENE_FILE',useEnv = False) # get work_2d_scene_file print(('SceneControl: Info. Checking script file: %s') %script) # old Scriptname oldname = nuke.Root()["name"].value() # Nuke set filename nuke.Root()["name"].setValue(script) # check if folder exists folder = os.path.dirname(script) if not os.path.exists(folder): os.makedirs(folder) else: # folder existing. Moving on pass # check if file exists if os.path.isfile(script): if owrite: # good to go: change write nodes first updateWriteNodePaths() set_shot() nuke.scriptSave() else: s = "SceneControl. Overwrite Nuke Script? %s" % script overwrite = nuke.ask(s) if overwrite: # good to go: change write nodes first updateWriteNodePaths() set_shot() nuke.scriptSave() else: nuke.Root()["name"].setValue(oldname) else: # good to go: change write nodes first updateWriteNodePaths() set_shot() nuke.scriptSave() def increment_major_version(): sceneControl = getSceneControl() k = sceneControl.knobs() major = k["major_version"].getValue() major = int(major) + 1 k["major_version"].setValue(major) k["minor_version"].setValue(1) # call save script save_script() return def increment_minor_version(): sceneControl = getSceneControl() k = sceneControl.knobs() minor = k["minor_version"].getValue() minor = int(minor) + 1 k["minor_version"].setValue(minor) # call save script save_script() return # framerange def get_framerange_OLD(node): ''' # TODO: ftrack query or KEnv query # Connect to FTrack frameStart = 1001 frameCutIn = 1010 frameCutOut = 1100 frameEnd = 1109 n = nuke.thisNode() k = n.knobs() sequence = k["sequence"].getText() shot = k["shot"].getText() user = k["shortname"].getText() if user == "": nuke.message("Please fill out your shortname in the User field. E.g. \"ms\"") return try: conn = FTrackConnector(shortname=user) project = conn.getProject("drr") shot = project.getShot(sequence, shot) frameStart = shot.get("custom_attributes").get("fstart") frameCutIn = shot.get("custom_attributes").get("fcutin") frameCutOut = shot.get("custom_attributes").get("fcutout") frameEnd = shot.get("custom_attributes").get("fend") except Exception as e: nuke.message( "No Connection could be established. Check Firewall and enable 104.155.61.233 Port 443\n\n" + str(e)) node.knob("fStart").setValue(int(frameStart)) node.knob("fCutIn").setValue(int(frameCutIn)) node.knob("fCutOut").setValue(int(frameCutOut)) node.knob("fEnd").setValue(int(frameEnd)) return None ''' def get_framerange(node): import ftrack_tools sceneControl = getSceneControl() k = sceneControl.knobs() proj = k['project'].value() seq = k['sequence'].value() shot = k['shot'].value() # ftrack query p = ftrack_tools.get_project(proj) if proj == 'HOTZ': proj = 'HOT' shotcode = proj + '_' + seq + '_' + shot if k["debug"].getValue(): print(('SceneControl: Debug. Project: %s') %proj) print(('SceneControl: Debug. Sequence: %s') % seq) print(('SceneControl: Debug. Shot: %s') % shot) print(('SceneControl: Debug. FTrack Shotcode: %s') %shotcode) s = p.get_shot(shotcode) st,en = s.get_framerange() ha = s.get_handles() k['fStart'].setValue(int(st)) k['fCutIn'].setValue(int(st) + int(ha)) k['fEnd'].setValue(int(en)) k['fCutOut'].setValue(int(en) - int(ha)) return None def set_framerange(node): frameCutIn = node.knob("fCutIn").getValue() frameCutOut = node.knob("fCutOut").getValue() nuke.root()["first_frame"].setValue(frameCutIn) nuke.root()["last_frame"].setValue(frameCutOut) return None def remove_expressions(): #todo: create **kwargs for replacement n = nuke.thisNode() k = n.knobs() nodes = nuke.allNodes() for no in nodes: if no.Class() == "Read" or no.Class() == "DeepRead" or no.Class() == "Write": s = no.knob("file").getValue() k["eval_helper"].setValue(s) res = k["eval_helper"].evaluate() res = res.replace("\\", "/") res = res.replace("//hades/p/_projekte/DRR", "$env(JOB)") s = no.knob("file").setValue(res) return None def remove_expression_links(): nodes = nuke.allNodes() for n in nodes: if n.Class() == "Read" or n.Class() == "DeepRead" or n.Class() == "Write": for k in n.knobs(): n.knobs()[k].clearAnimated() return None def replace_frame_with_padded_frames(): nodes = nuke.allNodes() for n in nodes: if n.Class() == "Read" or n.Class() == "DeepRead": file = n.knob("file").getValue() sub = file.split(".")[-2] file = file.replace(sub, "####") n.knob("file").setValue(file) return None # layer def get_layer_versions(): # TODO: filter out temporary files: tmp, temp, ifd, ass sceneControl = getSceneControl() k = sceneControl.knobs() # get renderpath to look for layers path = kenvQuery('RENDER_3D_DIR') t = k["task"].value() task = '_' + t folder = os.path.dirname(str(path)) if not os.path.exists(folder): msg = "SceneControl. Error.\nNo renders found in:\n%s\nIs the task %s correct?" % (path, t) nuke.message(msg) return # find top folders in renderdir of current shot in current department folders = [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name))] # debug if k["debug"].getValue(): print(('SceneControl: Debug. Folders found: %s') %folders) # dict holding info about layer and their version. layer_dict = {} for f in folders: print(('SceneControl: Info: Adding folder: %s') %f) # extract layer name lay = f.split('.')[1] pattern = re.compile('_[vV]\d+') layer = re.sub(pattern, "", lay) layer = layer.replace(task, '') if k["debug"].getValue(): print(('SceneControl: Debug. Layer: %s') % layer) # extract version string pattern2 = re.compile('[vV]\d+') ver = pattern2.findall(f) version = ver[-1].replace('v', '').replace('V', '') version = int(version) if k["debug"].getValue(): print(('SceneControl: Debug. Version: %s') % version) # if layer is already loaded if layer in layer_dict: # check if version in dict is smaller than found version if layer_dict[layer] < version: layer_dict[layer] = version else: pass else: layer_dict[layer] = version if k["debug"].getValue(): print(('SceneControl: Debug. get_layer_version()) Layerdict: %s') % layer_dict) return layer_dict def get_layer_versions_OLD(): sceneControl = getSceneControl() k = sceneControl.knobs() # renderpath = '//hades/p/_projekte/HOTZ/500_renders/Shots/001/010' # path = kenvGetRenderPath() path = kenvQuery('RENDER_3D_DIR') task = k["task"].value() folder = os.path.dirname(str(path)) if not os.path.exists(folder): msg = "SceneControl. Error.\nNo renders found in:\n%s\nIs the Task %s correct?" % (path, task) nuke.message(msg) return # find top folders in renderdir of current shot in current department folders = [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name))] # debug if k["debug"].getValue(): print(('SceneControl: Debug. Folders found: %s') %folders) # dict holding info about layer and their version. BEN:3, SOR:4, ENV:1 layer_dict = {} for f in folders: print(('SceneControl: Info: Adding folder: %s') %f) # TODO: also add layers with variants. Eg. DRR Layer example: HOT_shots_001_010.beauty_light_v001/HOT_shots_001_010.beauty_light_v001.1023.exr try: layer = f.split('.')[1].split('_')[0] except: print(('SceneControl: Error. Layer %s is not conform in naming. Skipping.') %f) break version = int(f.split('_')[-1].replace('v', '')) if layer in layer_dict: # check if version in dict is smaller than found version if layer_dict[layer] < version: layer_dict[layer] = version else: pass else: layer_dict[layer] = version if k["debug"].getValue(): print(('SceneControl: Debug. get_layer_version()) Layerdict: %s') % layer_dict) return layer_dict def update_layer(): n = nuke.thisNode() # get newest files on disk layer_dict = get_layer_versions() if bool(layer_dict) is True: layer_dict_new_entries = OrderedDict(sorted(layer_dict.items(), key=lambda t: t[0])) nu = n['layerNum'].getValue() num = int(nu) # get new entries for layer, version in layer_dict.items(): if num < 1: c = 0 else: c = num for i in range(1, num + 1): if n.knob("layer_name_" + str(i)) is not None and n.knob("layer_name_" + str(i)).getValue() == layer: # layer already in list. Just update version n.knob("layer_version_" + str(i)).setValue(version) del layer_dict_new_entries[layer] break # new entries if len(layer_dict_new_entries) > 0: c += 1 for layer, version in layer_dict_new_entries.items(): k = nuke.String_Knob("layer_name_" + str(c), str(c)) n.addKnob(k) n.knob("layer_name_" + str(c)).setValue(layer) # Version k = nuke.Int_Knob("layer_version_" + str(c), "version") n.addKnob(k) n.knob("layer_version_" + str(c)).clearFlag(nuke.STARTLINE) n.knob("layer_version_" + str(c)).setValue(version) # Button Read func = "sceneControl.create_readnode(" + str(c) + ")" name = "create_readnode_" + str(c) k = nuke.PyScript_Knob(name, "Read", func) n.addKnob(k) # Button Deep Read func = "sceneControl.create_deepreadnode(" + str(c) + ")" name = "create_deepreadnode_" + str(c) k = nuke.PyScript_Knob(name, "Deep", func) n.addKnob(k) # Button Crypto #func = "sceneControl.create_readnode(" + str(c) + ")" #name = "create_readnode" + str(c) #k = nuke.PyScript_Knob(name, "Crypto", func) #n.addKnob(k) # Include in publish k = nuke.Boolean_Knob("include_in_publish_" + str(c), "Publish") n.addKnob(k) n.knob("include_in_publish_" + str(c)).clearFlag(nuke.STARTLINE) n.knob("include_in_publish_" + str(c)).setValue(1) n.knob("include_in_publish_" + str(c)).setTooltip("Include this layer in publish.") num = num + 1 c = c + 1 n.knob("layerNum").setValue(c - 1) layer_dict = None return else: # dict is empty return def remove_layer(c): n = nuke.thisNode() # remove entire line k = "layer_name_" + str(c) n.removeKnob(n.knobs()[k]) k = "layer_version_" + str(c) n.removeKnob(n.knobs()[k]) k = "create_readnode_" + str(c) n.removeKnob(n.knobs()[k]) k = "create_deepreadnode_" + str(c) n.removeKnob(n.knobs()[k]) k = "include_in_publish_" + str(c) n.removeKnob(n.knobs()[k]) # adjust number of layers nu = n["layerNum"].getValue() nu = nu - 1 n.knob("layerNum").setValue(int(nu)) if n.knob("layerNum").getValue() < 0: n.knob("layerNum").setValue(0) return def remove_all_layers(node): n = nuke.thisNode() nu = n["layerNum"].getValue() num = int(nu) for i in range(num, 0, -1): remove_layer(i) return # publish // redo this def publish_shot(): n = nuke.thisNode() k = n.knobs() print ("SceneControl: Checking Versions...") maximum = return_highest_layer_version() major = k["major_version"].getValue() if major < maximum: if nuke.ask( 'SceneControl: Layer found with higher version than the Major file version. Continue with publish?'): pass else: "SceneControl: Terminating Publish" return print ("SceneControl: Publishing Shot") # sequence sequence = k["sequence"].getText() # shot shot = k["shot"].getText() # cutIn and cutOut frameCutIn = n.knob("fCutIn").getValue() frameCutOut = n.knob("fCutOut").getValue() # precompCutIn and precompCutOut precompframeCutIn = n.knob("pCutIn").getValue() precompframeCutOut = n.knob("pCutOut").getValue() # eye eye = n.knob("eye").getValue() # rendered on studio funk farm studioFunkRender = n.knob("studio_funk_render").getValue() # comment comment = k["comment"].getText() # shortname shortname = k["user"].getText() if shortname == "": nuke.message("Please fill out your shortname in the User field. E.g. \"ms\"") return # precomp render path major = k["major_version"].getValue() major = "v" + str(int(major)).zfill(3) path = k["comp_output_path"].getText() path = path.replace("MAJORVERSION", str(major)) output = k["comp_output_file"].getText() output = output.replace("MAJORVERSION", str(major)) path = path.replace("\\", "/") precomp = "%s/%s" % (path, output) # evaluate expressions k["eval_helper"].setValue(precomp) precomp = k["eval_helper"].evaluate() precomp = precomp.replace("\\", "/") frames = precomp.split(".")[-2] precomp = precomp.replace(frames, "####") precomp_dir = os.path.dirname(precomp) # debug debug = k["Debug"].getValue() # gather Layers and versions to publish (exclude flagged Layers) layernum = k["layerNum"].getValue() num = int(layernum) layer = {} publish = {} metadata = {} skip_copy_layers = [] for c in range(1, num + 1, 1): layername = n.knob("layer_name_" + str(c)).getValue() layerversion = n.knob("layer_version_" + str(c)).getValue() if n.knob("include_in_publish_" + str(c)).getValue() == 1: layer[layername] = str(int(layerversion)).zfill(3) if n.knob("copy_layer_" + str(c)).getValue() == 1: skip_copy_layers.append(layername) # search for readnodes that are linked in SceneControl meta = return_readnodes("layer_version_" + str(c)) node = nuke.toNode(str(meta)) if node is not None: if node.metadata() != {}: for k, v in node.metadata().iteritems(): # print (k > v) if k == "exr/DRR_Scene": metadata[layername + "_Scene"] = v if k == "exr/DRR_Shader": metadata[layername + "_Shader"] = v if k == "exr/DRR_FXAssembly": metadata[layername + "_FXAssembly"] = v else: print ("SceneControl: No Metadata availible") else: # should not be included in publish pass """ publish["nukescript"] = nukescript # //hades/p/_projekte/DRR/02_Shots/SEQ_0200/SHOT_0200_0010/04_Lighting/02_work/nuke/lighting/ publish["sequence"] = sequence # 0160 publish["shot"] = shot # 0040 publish["cut_in"] = frameCutIn # 1009 publish["cut_out"] = frameCutOut # 1109 publish["precomp_cut_in"] = precomp_cut_in # 1009 publish["precomp_cut_out"] = precomp_cut_out # 1009 publish["comment"] = comment # "My Comment\nAnother comment.\nYet another comment." publish["shortname"] = shortname # "ms" publish["layer"] = layer # {"CHAR": "011", "VOL": "011", "DUS": "009", "ENV": "011"} publish["skip_copy_layers"] = skip_copy_layers # ("CHAR","ENV") publish["metadata"] = layer # {"CHAR_Scene": "/path/to/desertRuins_MOD_v037.003.json", "CHAR_Shader": "/path/to/desertRuins_MOD_v037.003.shdAssembly.json", "CHAR_FXAssembly": "/path/to/FXAssembly"} publish["precomp_dir"] = precomp_dir # //hades/p/_projekte/DRR/02_Shots/SEQ_0160/SHOT_0160_0040/04_Lighting/02_work/nuke/lighting/render/SHOT_0160_0040_LIG_v001 publish["email_recipients"] = ["martin@saechsinger.de"] """ save_script(publish=True) # nukescript nukescript = nuke.Root()["name"].getValue() # prepare publish dict publish["nukescript"] = nukescript publish["sequence"] = sequence publish["cut_in"] = frameCutIn publish["cut_out"] = frameCutOut publish["shot"] = shot publish["comment"] = comment publish["shortname"] = shortname publish["layer"] = layer publish["skip_copy_layers"] = skip_copy_layers publish["precomp_dir"] = precomp_dir publish["metadata"] = metadata publish["eye"] = eye if studioFunkRender: publish["precomp_cut_in"] = precompframeCutIn publish["precomp_cut_out"] = precompframeCutOut # save script (scene control will get deleted) # do the publish if debug == 1.0: reload(publisher) print ("SceneControl: ____Test Publish:____") for k, v in publish.items(): print (k, '>', v) else: reload(publisher) for k, v in publish.items(): print (k, '>', v) publisher.Lighting(**publish).publish() return None def return_readnodes(layername): nodes = nuke.allNodes() for n in nodes: if n.Class() == "Read": filepath = n.knob("file").getValue() if layername in filepath: return n.name() return None def create_readnode_old(c, autoconnect=None): # TODO: create just one function for read, deep read and cryptomatte n = nuke.thisNode() k = n.knobs() layer = n.knob("layer_name_" + str(c)).getValue() a = "layer_version_" + str(c) version = "v[format %%03d [value SceneControl.%s]]" % a # replace [ASSETVERSION] with version of SceneControl # Read path = k["output_path"].getText() output = k["output_file"].getText() path = path.replace("LAYERVERSION", str(version)) path = path.replace("\\", "/") output = output.replace("LAYERVERSION", str(version)) path = path.replace("LAYER", str(layer)) output = output.replace("LAYER", str(layer)) file = "%s/%s" % (path, output) k["eval_helper"].setValue(file) checkfile = k["eval_helper"].evaluate() checkfile = checkfile.replace("\\", "/") # create Read __________________________________________________ read = nuke.nodes.Read() read.setName(layer) read["file"].setValue(file) missing = k["missing_frames"].getText() if missing == "error": read["on_error"].setValue(0) elif missing == "black": read["on_error"].setValue(1) elif missing == "checkerboard": read["on_error"].setValue(2) elif missing == "nearest frame": read["on_error"].setValue(3) read["first"].setExpression("[value SceneControl.fStart]") read["origfirst"].setExpression("[value SceneControl.fStart]") read["last"].setExpression("[value SceneControl.fEnd]") read["origlast"].setExpression("[value SceneControl.fEnd]") read["label"].setValue("scnCtrl") # position Read if autoconnect is None: # connect to selectedNode try: selectedNode = nuke.selectedNode() except: selectedNode = None if selectedNode is not None: selectedNode.setInput(0, read) read.setXYpos(selectedNode.xpos(), selectedNode.ypos() - 150) else: # connect to dots with starts with layer name dot = find_node_by_type(layer, "Dot") if dot is not None: dot.setInput(0, read) read.setXYpos(dot.xpos() - 37, dot.ypos() - 150) else: pass dot = None return def create_deepreadnode_old(c, autoconnect=None): n = nuke.thisNode() k = n.knobs() layer = n.knob("layer_name_" + str(c)).getValue() a = "layer_version_" + str(c) version = "v[format %%03d [value SceneControl.%s]]" % a # replace [ASSETVERSION] with version of SceneControl # DeepRead __________________________________________________ path = k["output_path"].getText() output = k["deep_output_file"].getText() path = path.replace("LAYERVERSION", str(version)) path = path.replace("\\", "/") output = output.replace("LAYERVERSION", str(version)) path = path.replace("LAYER", str(layer)) output = output.replace("LAYER", str(layer)) deep_subfolder = k["deep_subfolder"].getText() if not deep_subfolder: file = "%s/%s" % (path, output) else: file = "%s/%s/%s" % (path, deep_subfolder, output) k["eval_helper"].setValue(file) checkfile = k["eval_helper"].evaluate() checkfile = checkfile.replace("\\", "/") # create DeepRead read = nuke.nodes.DeepRead() read.setName(layer + "_Deep") read["file"].setValue(file) missing = k["missing_frames"].getValue() if missing == "error": read["on_error"].setValue(0) elif missing == "black": read["on_error"].setValue(1) elif missing == "checkerboard": read["on_error"].setValue(2) elif missing == "nearest frame": read["on_error"].setValue(3) read["on_error"].setValue(1) read["first"].setExpression("[value SceneControl.fStart]") read["origfirst"].setExpression("[value SceneControl.fStart]") read["last"].setExpression("[value SceneControl.fEnd]") read["origlast"].setExpression("[value SceneControl.fEnd]") read["label"].setValue("scnCtrl") # position Deep Read if autoconnect is None: # connect to selectedNode try: selectedNode = nuke.selectedNode() except: selectedNode = None if selectedNode is not None: read.setXYpos(selectedNode.xpos() - 37, selectedNode.ypos() - 25) else: # connect to dots with starts with layer name dot = find_node_by_type(layer + "_Deepread", "Dot") if dot is not None: dot.setInput(0, read) read.setXYpos(dot.xpos() - 50, dot.ypos() - 150) else: pass dot = None return def return_highest_layer_version(): n = nuke.thisNode() k = n.knobs() # gather Layers and versions to publish (exclude flagged Layers) layernum = k["layerNum"].getValue() num = int(layernum) maximum = 1 for c in range(1, num + 1, 1): value = n.knob("layer_version_" + str(c)).getValue() if value > maximum: maximum = value print ("SceneControl: Highest Version is: %s" % int(maximum)) return int(maximum) def debugQuery(): sceneControl = getSceneControl() k = sceneControl.knobs() # element element = k['element'].value() if element is None or len(element)==0: element = 'None' # info info = k['info'].value() if info is None or len(info)==0: info = 'None' print('SceneControl: Debug kenv query:') print('PROJECT: ' + os.environ['PROJECT']) print('SEQUENCE: ' + k['sequence'].value()) print('SHOT: ' + k['shot'].value()) print('DEPT: ' + k['dept'].value()) print('TASK: ' + k['task'].value()) print('MAJOR_VERSION: ' + str(int(k['major_version'].value()))) print('MINOR_VERSION: ' + str(int(k['minor_version'].value()))) print('ELEMENT: ' + element) print('INFO: ' + info) print('USER_SHORT: ' + k['user'].value()) print('EXT: exr') print('APP_ID: nuke') return # deprecated def load_precomp(): major = nuke.thisNode().knob("major_version").getValue() major = "v" + str(int(major)).zfill(3) n = nuke.thisNode() k = n.knobs() path = k["comp_output_path"].getText() path = path.replace("MAJORVERSION", str(major)) output = k["comp_output_file"].getText() output = output.replace("MAJORVERSION", str(major)) path = path.replace("\\", "/") file = "%s/%s" % (path, output) # dance the resolve dance k["precomp_output"].setValue(file) precomp = k["precomp_output"].evaluate() precomp = precomp.replace("\\", "/") sub = precomp.split(".")[-2] precomp = precomp.replace(sub, "####") # create the read file read = nuke.nodes.Read() read.setName("Precomp") read["file"].setValue(precomp) read["first"].setExpression("[value SceneControl.fStart]") read["origfirst"].setExpression("[value SceneControl.fStart]") read["last"].setExpression("[value SceneControl.fEnd]") read["origlast"].setExpression("[value SceneControl.fEnd]") try: selectedNode = nuke.selectedNode() except: selectedNode = None if selectedNode is not None: read.setXYpos(selectedNode.xpos() + 100, selectedNode.ypos()) return None def create_writenode(): major = nuke.thisNode().knob("major_version").getValue() major = "v" + str(int(major)).zfill(3) write = nuke.nodes.Write() write.setName("Precomp") n = nuke.thisNode() k = n.knobs() path = k["comp_output_path"].getText() # path = path.replace("MAJORVERSION", str(major)) output = k["comp_output_file"].getText() # output = output.replace("MAJORVERSION", str(major)) path = path.replace("\\", "/") file = "%s/%s" % (path, output) write["file"].setValue(file) write["views"].setValue("left") write["file_type"].setValue("exr") write["create_directories"].setValue(1) write["metadata"].setValue(4) try: selectedNode = nuke.selectedNode() except: selectedNode = None if selectedNode is not None: write.setInput(0, selectedNode) write.setXYpos(selectedNode.xpos(), selectedNode.ypos() + 66) return def remove_scnctrl_reads(node): nodes = nuke.allNodes() for n in nodes: if n.Class() == "Read" or n.Class() == "DeepRead": s = n.knob("label").getValue() if s.startswith("scnCtrl"): nuke.delete(n) else: pass return