No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

proxyTools.py 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. ########################################################################
  2. ### PROXY TOOLS 1.0
  3. ### by Brian Willard
  4. ### mybikeislost@gmail.com
  5. ###
  6. ### Generates reformat and write nodes for rendering proxies on a farm
  7. ### option to process all read nodes, selected read nodes, or all quicktime files in a script
  8. ### reads metadata to determine filetype to handle quicktime files with and without and extension.
  9. ### process sequences proxy subfolders
  10. ### option to create a read node that reflects the new proxy/fullres path
  11. ### TODO: add support for r3d files
  12. ###
  13. ###
  14. ########################################################################
  15. import re
  16. import os
  17. import sys
  18. import nuke
  19. import nukescripts
  20. def proxyTools():
  21. def _buildPROXIES(selection, processPlates, createRead, formatFullVal, formatProxyVal, formatProxySizeVal):
  22. print '\n######## PROXYTOOLS Variables ########\n'
  23. print 'selection: ' +selection
  24. print 'processPlates: ' +processPlates
  25. print 'createRead: ' +str(createRead)
  26. print 'formatFullVal: ' +formatFullVal
  27. print 'formatProxyVal: ' +formatProxyVal
  28. print 'formatProxySizeVal: ' +formatProxySizeVal
  29. print '\n###############################\n'
  30. ### Figure out what we're rendering and build a list (all, selected, quicktime)
  31. readlist = []
  32. if selection ==('selected'):
  33. readlist= [i for i in nuke.selectedNodes() if i.Class() =='Read']
  34. if readlist ==[]:
  35. nuke.message('no Read nodes selected!')
  36. return
  37. if selection == ('all'):
  38. readlist= [i for i in nuke.allNodes() if i.Class() =='Read']
  39. if selection == ('quicktime'):
  40. readlist = [i for i in nuke.allNodes() if i.metadata('input/filereader') == 'QuickTime']
  41. ### Figure out if we're rendering fullres, proxies, or both
  42. if processPlates == 'both':
  43. processProxy = True
  44. processFull = True
  45. print 'rendering Proxy and FullRes'
  46. if processPlates == 'proxy':
  47. processFull = False
  48. processProxy = True
  49. print 'rendering Proxy only'
  50. if processPlates == 'full':
  51. processFull = True
  52. processProxy = False
  53. print 'rendering FullRes only'
  54. if sys.platform.startswith('win'):
  55. pathslash = ('\\')
  56. else:
  57. pathslash = ('/')
  58. for i in readlist:
  59. curNode = i
  60. truncpath = i.knob('file').value().rfind(pathslash)
  61. truncfile = i.knob('file').value().rfind('.mov')
  62. dirpath = i.knob('file').value()[:truncpath]
  63. print '\n######## Begin ' +i.name() + ' ########\n'
  64. ### Get filename and padding info from source knob
  65. if i.metadata('input/filereader') == 'QuickTime':
  66. filetype='quicktime'
  67. filepath = i.knob('file').getValue('fileName')
  68. filename = os.path.splitext(i.knob('file').getValue('fileName').split(pathslash)[-1])[-2]
  69. padding = 4
  70. print 'source file is a quicktime '
  71. fullFmt = str(int((i.format().width()))) +'x' +str(int((i.format().height())))
  72. print 'filepath: ' +filepath
  73. print 'filename: ' +filename
  74. print 'fullFmt: ' +fullFmt
  75. resFolder = False
  76. else:
  77. filetype='imgSequence'
  78. filepath = i.knob('file').getValue('fileName')
  79. filename =(i.knob('file').getValue('fileName')).split('.')[-3].split(pathslash)[-1]
  80. parentfolder = (i.knob('file').getValue('fileName')).split('.')[-3].split(pathslash)[-2]
  81. fullFmt = str(int((i.format().width()))) +'x' +str(int((i.format().height())))
  82. print 'source file is an image sequence'
  83. print 'filepath: ' +filepath
  84. print 'filename: ' +filename
  85. print 'parentfolder: ' +parentfolder
  86. print 'fullFmt: ' +fullFmt
  87. if parentfolder == fullFmt:
  88. resFolder = True
  89. print 'we are in a resolution folder, rendering 1 level up'
  90. dirpath = os.sep.join(dirpath.split(pathslash)[:-1])
  91. print 'adjusted output path is: ' +dirpath
  92. else:
  93. resFolder = False
  94. print 'fullres not in a format folder, creating sub folders'
  95. #print 'adjusted output path is: ' +dirpath
  96. number = re.search('(%+\d+d)|(#+)|(%d)' , filepath)
  97. if number:
  98. padding = len(number.group(1))
  99. path = i.knob('file').value()
  100. if path.find('rnd'):
  101. os.path.basename(path)
  102. foldername = filename + '_IMG'
  103. # try:
  104. # os.mkdir(dirpath +pathslash +foldername)
  105. # except OSError: pass
  106. ######################################################
  107. ### BUILD PROXY
  108. ### FILTER TYPES BY PROXY RASTER: Full (Impulse), half (Cubic), quarter (Cubic)
  109. ###
  110. ######################################################
  111. if processProxy == True:
  112. ### CREATE FORMAT
  113. m = nuke.createNode('Reformat', inpanel = False)
  114. m.setInput(0,i)
  115. m.setXYpos((int(i.knob('xpos').value())), (int(i.knob('ypos').value())+125))
  116. m.knob('type').setValue('scale')
  117. if formatProxySizeVal ==('full'):
  118. sizeVal = 1.0
  119. m.knob('filter').setValue('Impulse')
  120. elif formatProxySizeVal ==('half'):
  121. sizeVal = 0.5
  122. m.knob('filter').setValue('Cubic')
  123. elif formatProxySizeVal ==('quarter'):
  124. sizeVal = 0.25
  125. m.knob('filter').setValue('Cubic')
  126. m.knob('scale').setValue(sizeVal)
  127. m.knob('label').setValue('Filter: '+ m.knob('filter').value()+ '\nProxy Size: ' +formatProxySizeVal)
  128. ### CREATE WRITE
  129. n = nuke.createNode('Write', inpanel=False)
  130. n.setXYpos((int(m.knob('xpos').value())), (int(m.knob('ypos').value())+50))
  131. proxyFmt = str(int((i.format().width())*sizeVal)) +'x' +str(int((i.format().height())*sizeVal))
  132. print 'proxyFmt: ' +proxyFmt
  133. if formatProxyVal ==('exr'):
  134. if resFolder == True:
  135. n.knob('file').setValue(dirpath +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
  136. else:
  137. n.knob('file').setValue(dirpath +pathslash + foldername +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
  138. n.knob('file_type').setValue('exr')
  139. n.knob('channels').setValue('all')
  140. n.knob('colorspace').setValue(int(i.knob('colorspace').getValue()))
  141. n.knob('premultiplied').setValue(i.knob('premultiplied').value())
  142. n.knob('raw').setValue(i.knob('raw').value())
  143. n.knob('stereo').setValue(False)
  144. elif formatProxyVal ==('jpeg'):
  145. n.knob('file_type').setValue('jpeg')
  146. n.knob('channels').setValue('all')
  147. n.knob('_jpeg_quality').setValue(0.97)
  148. if resFolder == True:
  149. n.knob('file').setValue(dirpath +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.jpg')
  150. else:
  151. n.knob('file').setValue(dirpath +pathslash + foldername +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.jpg')
  152. n.knob('disable').setExpression('!inrange(frame, '+ str(i.knob('first').value()) + ', ' + str(i.knob('last').value()) + ')',0)
  153. n.knob('label').setValue('PROXY \n Format: ' + proxyFmt)
  154. print 'Proxy output: ' +n.knob('file').getValue()
  155. ######################################################
  156. ### BUILD FULL RES
  157. ###
  158. ###
  159. ######################################################
  160. #move 'dot' up in DAG
  161. if processFull == True:
  162. d = nuke.createNode('Dot', inpanel=False)
  163. d.setInput(0,i)
  164. d.setXYpos((int(i.knob('xpos').value())+160), (int(i.knob('ypos').value())+45))
  165. o = nuke.createNode('Write', inpanel=False)
  166. o.setInput(0,d)
  167. o.setXYpos((int(d.knob('xpos').value()-33)), (int(d.knob('ypos').value())+120))
  168. fullFmt = str(o.format().width()) +'x' +str(o.format().height())
  169. if formatFullVal ==('exr'):
  170. o.knob('file_type').setValue('exr')
  171. o.knob('channels').setValue('all')
  172. o.knob('colorspace').setValue(int(i.knob('colorspace').getValue()))
  173. o.knob('premultiplied').setValue(i.knob('premultiplied').value())
  174. if resFolder == True:
  175. o.knob('file').setValue(dirpath+pathslash +fullFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
  176. else:
  177. o.knob('file').setValue(dirpath+pathslash + foldername +pathslash +fullFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
  178. o.knob('raw').setValue(i.knob('raw').value())
  179. o.knob('stereo').setValue(False)
  180. elif formatFullVal ==('jpeg'):
  181. o.knob('file_type').setValue('jpeg')
  182. o.knob('channels').setValue('all')
  183. o.knob('_jpeg_quality').setValue(0.97)
  184. o.knob('file').setValue(dirpath+pathslash + foldername +pathslash +fullFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.jpg')
  185. o.knob('label').setValue('FULL \n Format: [value format.w]x[value format.h]')
  186. o.knob('disable').setExpression('!inrange(frame, '+ str(i.knob('first').value()) + ', ' + str(i.knob('last').value()) + ')',0)
  187. print 'FullRes output: ' +o.knob('file').getValue()
  188. ######################################################
  189. ### CREATE READ FROM OUR PROXY/FULL RASTER RENDERS
  190. ###
  191. ###
  192. ######################################################
  193. if createRead == True:
  194. p = nuke.createNode('Read', inpanel = False)
  195. print '\n#### generating ' +p.name() +'####\n'
  196. if processFull== True:
  197. p.knob('file').setValue((o.knob('file').getValue('fileName')))
  198. else:
  199. p.knob('file').setValue((i.knob('file').getValue('fileName')))
  200. print 'file path: ' +p.knob('file').getValue('fileName')
  201. if processProxy == True:
  202. p.knob('proxy').setValue((n.knob('file').getValue('fileName')))
  203. print 'proxy path: ' +p.knob('proxy').getValue('fileName')
  204. p.knob('first').setValue(int(i.knob('first').value()))
  205. p.knob('last').setValue(int(i.knob('last').value()))
  206. p.knob('first').setValue(int(i.knob('origfirst').value()))
  207. p.knob('origlast').setValue(int(i.knob('origlast').value()))
  208. p.setXYpos((int(i.knob('xpos').value())), (int(i.knob('ypos').value())+300))
  209. print '\n######## Finished ' +i.name() + ' ########\n'
  210. class ProxyToolsPanel(nukescripts.PythonPanel):
  211. def __init__(self):
  212. nukescripts.PythonPanel.__init__(self, 'Proxy Tools v1.0', 'com.mybikeislost.ProxyTools')
  213. ### Create KNOBS
  214. self.processSelectionKnob = nuke.Enumeration_Knob('processSelection', 'Process Reads:', ['all', 'selected', 'quicktime'])
  215. self.processPlatesKnob = nuke.Enumeration_Knob('processPlates', 'Process Plates:', ['both', 'full', 'proxy'])
  216. self.createReadKnob = nuke.Boolean_Knob('create write node with our full/proxy paths from above', 'Create Read')
  217. self.dividerKnob = nuke.Text_Knob('div name','','')
  218. self.formatFullKnob = nuke.Enumeration_Knob('format', 'Full Res Format', ['exr', 'jpeg'])
  219. self.dividerKnob2 = nuke.Text_Knob('div name','','')
  220. self.formatProxyKnob = nuke.Enumeration_Knob('proxy_Format', 'Proxy Format:', ['jpeg', 'exr'])
  221. self.proxySizeKnob = nuke.Enumeration_Knob('proxy_Size', 'Proxy Size:', ['half', 'full', 'quarter'])
  222. self.dividerKnob3 = nuke.Text_Knob('div name','','')
  223. ### ADD KNOBS
  224. for k in ( self.processSelectionKnob, self.processPlatesKnob, self.createReadKnob, self.dividerKnob, self.formatFullKnob, self.dividerKnob2, self.formatProxyKnob, self.proxySizeKnob, self.dividerKnob3 ):
  225. self.addKnob( k )
  226. def showModalDialog(self):
  227. result = nukescripts.PythonPanel.showModalDialog(self)
  228. if result:
  229. selection = str(self.processSelectionKnob.value())
  230. processPlates = str(self.processPlatesKnob.value())
  231. createRead = self.createReadKnob.value()
  232. formatFullVal =str(self.formatFullKnob.value())
  233. formatProxyVal = self.formatProxyKnob.value()
  234. formatProxySizeVal = str(self.proxySizeKnob.value())
  235. _buildPROXIES(selection, processPlates, createRead, formatFullVal, formatProxyVal, formatProxySizeVal)
  236. def showProxyTools():
  237. ProxyToolsPanel().showModalDialog()
  238. showProxyTools()