1
2
3 import re
4 import os.path
5 import nuke
6 import nukescripts
7
8 prev_inrange = ""
9 prev_userrange = ""
10
11 -def flipbook(command, node, framesAndViews = None):
12 """Runs an arbitrary command on the images output by a node. This checks
13 to see if the node is a Read or Write and calls the function directly
14 otherwise it creates a temporary Write, executes it, and then calls
15 the command on that temporary Write, then deletes it.
16
17 By writing your own function you can use this to launch your own
18 flipbook or video-output programs.
19
20 Specify framesAndViews as a tuple if desired, like so: ("1,5", ["main"])
21 This can be useful when running without a GUI."""
22
23 if nuke.env['nc'] and command == nukescripts.framecycler_this:
24 raise RuntimeError("Framecycler is not available in NC mode.")
25
26 global prev_inrange
27 global prev_userrange
28
29 if node is None or (node.Class() == "Viewer" and node.inputs() == 0): return
30
31 a = int( nuke.numvalue(node.name()+".first_frame") )
32 b = int( nuke.numvalue(node.name()+".last_frame") )
33 if a < b:
34 a = int( nuke.numvalue("root.first_frame") )
35 b = int( nuke.numvalue("root.last_frame") )
36
37 try:
38 inrange= str( nuke.FrameRange(a, b, 1) )
39 except ValueError,e:
40
41
42
43
44 msg = e. __str__()
45 inrange = msg[ msg.index("(")+1: msg.index(")") ]
46
47 same_range = (inrange == prev_inrange)
48 prev_inrange = inrange
49
50 if same_range:
51 inrange = prev_userrange
52
53 if framesAndViews is None:
54 r = nuke.getFramesAndViews(label = "Frames to flipbook:", default = inrange, \
55 maxviews = 1)
56 if r is None: return
57 else:
58 r = framesAndViews
59
60 range_input = r[0]
61 views_input = r[1]
62
63 prev_userrange = range_input
64
65 f = nuke.FrameRange( range_input )
66
67 start =f.first()
68 end = f.last()
69 incr = f.increment()
70
71 if (start) < 0 or (end<0):
72 raise RuntimeError("Flipbook cannot be executed, negative frame range not supported(%s)." % ( str(f),) )
73
74 proxy = nuke.toNode("root").knob("proxy").value()
75
76 if (node.Class() == "Read" or node.Class() == "Write") and not proxy:
77 try:
78 command(node, start, end, incr, views_input)
79 except Exception, msg:
80 nuke.message("Error running flipbook:\n%s" % (msg,))
81 return
82
83 if node.Class() == "Viewer":
84 input_num = int(nuke.knob(node.name()+".input_number"))
85 input = node.input(input_num)
86 if input is None: return
87
88 if (input.Class() == "Read" or input.Class() == "Write") and not proxy:
89 try:
90 command(input, start, end, incr, views_input)
91 except Exception, msg:
92 nuke.message("Error running flipbook:\n%s" % (msg,))
93 return
94
95
96 flipbooktmp=""
97 if flipbooktmp == "":
98 try:
99 flipbooktmp = os.environ["FC_DISK_CACHE"]
100 except:
101 try:
102 flipbooktmp = os.environ["NUKE_DISK_CACHE"]
103 except:
104 flipbooktmp = nuke.value("preferences.DiskCachePath")
105
106 if len(views_input) > 1:
107 flipbookFileNameTemp = "nuke_tmp_flip.%04d.%V.rgb"
108 else:
109 flipbookFileNameTemp = "nuke_tmp_flip.%04d.rgb"
110 flipbooktmp = os.path.join(flipbooktmp, flipbookFileNameTemp)
111
112 if nuke.env['WIN32']:
113 flipbooktmp = re.sub("\\\\", "/", str(flipbooktmp))
114
115 fieldname="file"
116 if proxy:
117 fieldname="proxy"
118
119 write = nuke.createNode("Write", fieldname+" {"+flipbooktmp+"} "+"tile_color 0xff000000", inpanel = False)
120
121 input = node
122 if node.Class() == "Viewer":
123 input = node.input(int(nuke.knob(node.name()+".input_number")))
124 write.setInput(0, input)
125
126 try:
127
128 nuke.executeMultiple((write,), ([start,end,incr], ), views_input)
129 command(write, start, end, incr, views_input)
130 except Exception, msg:
131 nuke.message("Flipbook render failed:\n%s" % (msg,))
132 nuke.delete(write)
133