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
24
25 if nuke.env['ple'] and command == nukescripts.framecycler_this:
26 raise RuntimeError("Framecycler is not available in PLE mode.")
27
28 global prev_inrange
29 global prev_userrange
30
31 if node is None or (node.Class() == "Viewer" and node.inputs() == 0): return
32
33 a = int( nuke.numvalue(node.name()+".first_frame") )
34 b = int( nuke.numvalue(node.name()+".last_frame") )
35 if a < b:
36 a = int( nuke.numvalue("root.first_frame") )
37 b = int( nuke.numvalue("root.last_frame") )
38
39 try:
40 inrange= str( nuke.FrameRange(a, b, 1) )
41 except ValueError,e:
42
43
44
45
46 msg = e. __str__()
47 inrange = msg[ msg.index("(")+1: msg.index(")") ]
48
49 same_range = (inrange == prev_inrange)
50 prev_inrange = inrange
51
52 if same_range:
53 inrange = prev_userrange
54
55 if framesAndViews is None:
56 r = nuke.getFramesAndViews(label = "Frames to flipbook:", default = inrange, \
57 maxviews = (2 if nukescripts.framecycler_stereo_available() else 1))
58 if r is None: return
59 else:
60 r = framesAndViews
61
62 range_input = r[0]
63 views_input = r[1]
64
65 prev_userrange = range_input
66
67 f = nuke.FrameRange( range_input )
68
69 start =f.first()
70 end = f.last()
71 incr = f.increment()
72
73 if (start) < 0 or (end<0):
74 raise RuntimeError("Flipbook cannot be executed, negative frame range not supported(%s)." % ( str(f),) )
75
76 proxy = nuke.toNode("root").knob("proxy").value()
77
78 if (node.Class() == "Read" or node.Class() == "Write") and not proxy:
79 try:
80 command(node, start, end, incr, views_input)
81 except Exception, msg:
82 nuke.message("Error running flipbook:\n%s" % (msg,))
83 return
84
85 if node.Class() == "Viewer":
86 input_num = int(nuke.knob(node.name()+".input_number"))
87 input = node.input(input_num)
88 if input is None: return
89
90 if (input.Class() == "Read" or input.Class() == "Write") and not proxy:
91 try:
92 command(input, start, end, incr, views_input)
93 except Exception, msg:
94 nuke.message("Error running flipbook:\n%s" % (msg,))
95 return
96
97
98 flipbooktmp=""
99 if flipbooktmp == "":
100 try:
101 flipbooktmp = os.environ["FC_DISK_CACHE"]
102 except:
103 try:
104 flipbooktmp = os.environ["NUKE_DISK_CACHE"]
105 except:
106 flipbooktmp = nuke.value("preferences.DiskCachePath")
107
108 if len(views_input) > 1:
109 flipbookFileNameTemp = "nuke_tmp_flip.%04d.%V.rgb"
110 else:
111 flipbookFileNameTemp = "nuke_tmp_flip.%04d.rgb"
112 flipbooktmp = os.path.join(flipbooktmp, flipbookFileNameTemp)
113
114 if nuke.env['WIN32']:
115 flipbooktmp = re.sub("\\\\", "/", str(flipbooktmp))
116
117 fieldname="file"
118 if proxy:
119 fieldname="proxy"
120
121 write = nuke.createNode("Write", fieldname+" {"+flipbooktmp+"} "+"tile_color 0xff000000", inpanel = False)
122
123 input = node
124 if node.Class() == "Viewer":
125 input = node.input(int(nuke.knob(node.name()+".input_number")))
126 write.setInput(0, input)
127
128 try:
129
130 nuke.executeMultiple((write,), ([start,end,incr], ), views_input)
131 command(write, start, end, incr, views_input)
132 except Exception, msg:
133 nuke.message("Flipbook render failed:\n%s" % (msg,))
134 nuke.delete(write)
135