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
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)
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 _beforeRecordings={}
225
226 _afterRecordings={}
235
236 _beforeReplays={}
245
246 _afterReplays={}
255
256
257
259 if not callable(call):
260 raise ValueError("call must be a callable")
261 if type(args) != types.TupleType:
262 args = (args,)
263 if type(kwargs) != types.DictType:
264 raise ValueError("kwargs must be a dictionary")
265
266 try:
267 list.remove((call,args,kwargs))
268 except:
269 pass
270 list.append((call,args,kwargs))
271
273 if type(args) != types.TupleType:
274 args = (args,)
275 try:
276 list.remove((call,args,kwargs))
277 except:
278 pass
279
281 for f in list:
282 f[0](context, *f[1],**f[2])
283
284
285 beforeBackgroundRenders=[]
287 """Add code to execute before starting any background renders.
288 The call must be in the form of:
289 def foo(context):
290 pass
291
292 The context object that will be passed in is a dictionary containing the following elements:
293 id => The identifier for the task that's about to begin
294
295 Please be aware that the current Nuke context will not make sense in the callback (e.g. nuke.thisNode will return a random node).
296 """
297 _addBackgroundCallback(beforeBackgroundRenders, call, args, kwargs)
303
304
305
306
307
308
309
310
311
312
313
314 afterBackgroundFrameRenders=[]
316 """Add code to execute after each frame of a background render.
317 The call must be in the form of:
318 def foo(context):
319 pass
320
321 The context object that will be passed in is a dictionary containing the following elements:
322 id => The identifier for the task that's making progress
323 frame => the current frame number being rendered
324 numFrames => the total number of frames that is being rendered
325 frameProgress => the number of frames rendered so far.
326
327 Please be aware that the current Nuke context will not make sense in the callback (e.g. nuke.thisNode will return a random node).
328 """
329 _addBackgroundCallback(afterBackgroundFrameRenders, call, args, kwargs)
335
336 afterBackgroundRenders=[]
338 """Add code to execute after any background renders.
339 The call must be in the form of:
340 def foo(context):
341 pass
342
343 The context object that will be passed in is a dictionary containing the following elements:
344 id => The identifier for the task that's ended
345
346 Please be aware that the current Nuke context will not make sense in the callback (e.g. nuke.thisNode will return a random node).
347 """
348 _addBackgroundCallback(afterBackgroundRenders, call, args, kwargs)
354
355
356 filenameFilters={}
358 """Add a function to modify filenames before Nuke passes them to
359 the operating system. The first argument to the function is the
360 filename, and it should return the new filename. None is the same as
361 returning the string unchanged. All added functions are called
362 in backwards order."""
363 _addCallback(filenameFilters, call, args, kwargs, nodeClass)
367
391
392 validateFilenames={}
394 """Add a function to validate a filename in Write nodes. The first argument
395 is the filename and it should return a Boolean as to whether the filename is valid
396 or not. If a callback is provided, it will control whether the Render button of Write nodes
397 and the Execute button of WriteGeo nodes is enabled or not."""
398 _addCallback(validateFilenames, call, args, kwargs, nodeClass)
417
418
428
429 autoSaveFilters={}
431 """addAutoSaveFilter(filter) -> None
432
433 Add a function to modify the autosave filename before Nuke saves the current script on an autosave timeout.
434
435 Look at rollingAutoSave.py in the nukescripts directory for an example of using the auto save filters.
436
437 @param filter: A filter function. The first argument to the filter is the current autosave filename.
438 The filter should return the filename to save the autosave to."""
439 _addCallback(autoSaveFilters, filter, (), {}, 'Root')
440
444
448
449
450 autoSaveRestoreFilters={}
452 """addAutoSaveRestoreFilter(filter) -> None
453
454 Add a function to modify the autosave restore file before Nuke attempts to restores the autosave file.
455
456 Look at rollingAutoSave.py in the nukescripts directory for an example of using the auto save filters.
457
458 @param filter: A filter function. The first argument to the filter is the current autosave filename.
459 This function should return the filename to load autosave from or it should return None if the autosave file should be ignored."""
460 _addCallback(autoSaveRestoreFilters, filter, (), {}, 'Root')
461
465
469
470 autoSaveDeleteFilters={}
472 """addAutoSaveDeleteFilter(filter) -> None
473
474 Add a function to modify the autosave filename before Nuke attempts delete the autosave file.
475
476 Look at rollingAutoSave.py in the nukescripts directory for an example of using the auto save filters.
477
478 @param filter: A filter function. The first argument to the filter is the current autosave filename.
479 This function should return the filename to delete or return None if no file should be deleted."""
480 _addCallback(autoSaveDeleteFilters, filter, (), {}, 'Root')
481
485
489