1   
  2   
  3   
  4   
  5   
  6   
  7   
  8  import types 
  9  import nuke 
 10   
 11   
 12 -def _addCallback(dict, call, args, kwargs, nodeClass, node=None): 
  13    if not callable(call): 
 14      raise ValueError("call must be a callable") 
 15    if type(args) != types.TupleType: 
 16      args = (args,) 
 17    if type(kwargs) != types.DictType: 
 18      raise ValueError("kwargs must be a dictionary") 
 19    if dict.has_key(nodeClass): 
 20      list = dict[nodeClass] 
 21       
 22      try: 
 23        list.remove((call,args,kwargs,node)) 
 24      except: 
 25        pass 
 26      list.append((call,args,kwargs,node)) 
 27    else: 
 28      dict[nodeClass] = [(call,args,kwargs,node)] 
  29   
 31    if type(args) != types.TupleType: 
 32      args = (args,) 
 33    if dict.has_key(nodeClass): 
 34      list = dict[nodeClass] 
 35      try: 
 36        list.remove((call,args,kwargs,node)) 
 37      except: 
 38        pass 
  39   
 52   
 53  onUserCreates={} 
 63   
 64  onCreates={} 
 65 -def addOnCreate(call, args=(), kwargs={}, nodeClass='*'): 
  66    """Add code to execute when a node is created or undeleted""" 
 67    _addCallback(onCreates, call, args, kwargs, nodeClass) 
  69    """Remove a previously-added callback with the same arguments.""" 
 70    _removeCallback(onCreates, call, args, kwargs, nodeClass) 
  73   
 74  onScriptLoads={} 
 83   
 84  onScriptSaves={} 
 93   
 94  onScriptCloses={} 
103   
104  onDestroys={} 
106    """Add code to execute when a node is destroyed""" 
107    _addCallback(onDestroys, call, args, kwargs, nodeClass) 
 109    """Remove a previously-added callback with the same arguments.""" 
110    _removeCallback(onDestroys, call, args, kwargs, nodeClass) 
 113   
114  knobChangeds={} 
115 -def addKnobChanged(call, args=(), kwargs={}, nodeClass='*', node=None): 
 116    """Add code to execute when the user changes a knob 
117    The knob is availble in nuke.thisKnob() and the node in nuke.thisNode(). 
118    This is also called with dummy knobs when the control panel is opened 
119    or when the inputs to the node changes. The purpose is to update other 
120    knobs in the control panel. Use addUpdateUI() for changes that 
121    should happen even when the panel is closed.""" 
122    _addCallback(knobChangeds, call, args, kwargs, nodeClass, node) 
 128   
129  updateUIs={} 
130 -def addUpdateUI(call, args=(), kwargs={}, nodeClass='*'): 
 131    """Add code to execute on every node when things change. This is done 
132    during idle, you cannot rely on it being done before it starts updating 
133    the viewer""" 
134    _addCallback(updateUIs, call, args, kwargs, nodeClass) 
 136    """Remove a previously-added callback with the same arguments.""" 
137    _removeCallback(updateUIs, call, args, kwargs, nodeClass) 
 140   
141   
142  autolabels={} 
144    """Add code to execute on every node to produce the text to draw on it 
145    in the DAG. Any value other than None is converted to a string and used 
146    as the text. None indicates that previously-added functions should 
147    be tried""" 
148    _addCallback(autolabels, call, args, kwargs, nodeClass) 
 150    """Remove a previously-added callback with the same arguments.""" 
151    _removeCallback(autolabels, call, args, kwargs, nodeClass) 
 153    list = autolabels.get(nuke.thisClass()) 
154    if list: 
155      for f in list[::-1]: 
156        s = f[0](*f[1],**f[2]) 
157        if s != None: return s 
158    list = autolabels.get('*') 
159    if list: 
160      for f in list[::-1]: 
161        s = f[0](*f[1],**f[2]) 
162        if s != None: return s 
 163   
164   
165  beforeRenders={} 
174   
175  beforeFrameRenders={} 
184   
185  afterFrameRenders={} 
194   
195  afterRenders={} 
204   
205  renderProgresses={} 
207    """Add code to execute when the progress bar updates during any renders""" 
208    _addCallback(renderProgresses, call, args, kwargs, nodeClass) 
 214   
215   
216   
218    if not callable(call): 
219      raise ValueError("call must be a callable") 
220    if type(args) != types.TupleType: 
221      args = (args,) 
222    if type(kwargs) != types.DictType: 
223      raise ValueError("kwargs must be a dictionary") 
224     
225    try: 
226      list.remove((call,args,kwargs)) 
227    except: 
228      pass 
229    list.append((call,args,kwargs)) 
 230   
232    if type(args) != types.TupleType: 
233      args = (args,) 
234    try: 
235      list.remove((call,args,kwargs)) 
236    except: 
237      pass 
 238   
240    for f in list: 
241      f[0](context, *f[1],**f[2]) 
 242   
243   
244  beforeBackgroundRenders=[] 
246    """Add code to execute before starting any background renders.  
247    The call must be in the form of: 
248    def foo(context): 
249      pass 
250   
251    The context object that will be passed in is a dictionary containing the following elements: 
252    id => The identifier for the task that's about to begin 
253   
254    Please be aware that the current Nuke context will not make sense in the callback (e.g. nuke.thisNode will return a random node). 
255    """ 
256    _addBackgroundCallback(beforeBackgroundRenders, call, args, kwargs) 
 262   
263   
264   
265   
266   
267   
268   
269   
270   
271   
272   
273  afterBackgroundFrameRenders=[] 
275    """Add code to execute after each frame of a background render. 
276    The call must be in the form of: 
277    def foo(context): 
278      pass 
279   
280    The context object that will be passed in is a dictionary containing the following elements: 
281    id => The identifier for the task that's making progress 
282    frame => the current frame number being rendered 
283    numFrames => the total number of frames that is being rendered 
284    frameProgress => the number of frames rendered so far. 
285   
286    Please be aware that the current Nuke context will not make sense in the callback (e.g. nuke.thisNode will return a random node). 
287    """ 
288    _addBackgroundCallback(afterBackgroundFrameRenders, call, args, kwargs) 
 294   
295  afterBackgroundRenders=[] 
297    """Add code to execute after any background renders. 
298    The call must be in the form of: 
299    def foo(context): 
300      pass 
301   
302    The context object that will be passed in is a dictionary containing the following elements: 
303    id => The identifier for the task that's ended 
304   
305    Please be aware that the current Nuke context will not make sense in the callback (e.g. nuke.thisNode will return a random node). 
306    """ 
307    _addBackgroundCallback(afterBackgroundRenders, call, args, kwargs) 
 313   
314   
315  filenameFilters={} 
317    """Add a function to modify filenames before Nuke passes them to 
318    the operating system. The first argument to the function is the 
319    filename, and it should return the new filename. None is the same as 
320    returning the string unchanged. All added functions are called 
321    in backwards order.""" 
322    _addCallback(filenameFilters, call, args, kwargs, nodeClass) 
 326   
346   
347  validateFilenames={} 
349    """Add a function to validate a filename in Write nodes. The first argument 
350    is the filename and it should return a Boolean as to whether the filename is valid 
351    or not. If a callback is provided, it will control whether the Render button of Write nodes 
352    and the Execute button of WriteGeo nodes is enabled or not."""  
353    _addCallback(validateFilenames, call, args, kwargs, nodeClass) 
 372   
373   
375    import __main__ 
376    list = filters.get( 'Root' ) 
377    if list: 
378      for f in list: 
379        s = f[0](filename) 
380        filename = s 
381   
382    return filename 
 383   
384  autoSaveFilters={} 
386    """addAutoSaveFilter(filter) -> None 
387   
388    Add a function to modify the autosave filename before Nuke saves the current script on an autosave timeout. 
389   
390    Look at rollingAutoSave.py in the nukescripts directory for an example of using the auto save filters. 
391   
392    @param filter: A filter function.  The first argument to the filter is the current autosave filename. 
393    The filter should return the filename to save the autosave to.""" 
394    _addCallback(autoSaveFilters, filter, (), {}, 'Root') 
 395   
399   
403   
404   
405  autoSaveRestoreFilters={} 
407    """addAutoSaveRestoreFilter(filter) -> None 
408   
409    Add a function to modify the autosave restore file before Nuke attempts to restores the autosave file. 
410   
411    Look at rollingAutoSave.py in the nukescripts directory for an example of using the auto save filters. 
412   
413    @param filter: A filter function.  The first argument to the filter is the current autosave filename. 
414    This function should return the filename to load autosave from or it should return None if the autosave file should be ignored.""" 
415    _addCallback(autoSaveRestoreFilters, filter, (), {}, 'Root') 
 416   
420   
424   
425  autoSaveDeleteFilters={} 
427    """addAutoSaveDeleteFilter(filter) -> None 
428   
429    Add a function to modify the autosave filename before Nuke attempts delete the autosave file. 
430   
431    Look at rollingAutoSave.py in the nukescripts directory for an example of using the auto save filters. 
432   
433    @param filter: A filter function.  The first argument to the filter is the current autosave filename. 
434    This function should return the filename to delete or return None if no file should be deleted.""" 
435    _addCallback(autoSaveDeleteFilters, filter, (), {}, 'Root') 
 436   
440   
444