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.

makewritefromread.py 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. import os
  2. import nuke
  3. #
  4. # "Make Write from Read" v 1.2
  5. # Written by Hakan Blomdahl
  6. # how to install:
  7. #
  8. # import makewritefromread
  9. #
  10. # # Add extra Tools menu
  11. # mymenubar=nuke.menu("Nuke")
  12. # m=mymenubar.addMenu("Tools")
  13. #
  14. # # Create Tools menu for right click menu:
  15. # nodetoolbar = nuke.menu("Nodes")
  16. # t=nodetoolbar.addMenu("Tools")
  17. #
  18. # m.addCommand("Make Write of Read...", 'makewritefromread.make_write_from_read()', '')
  19. # t.addCommand("Make Write of Read...", 'makewritefromread.make_write_from_read()', '')
  20. def find_upstream_node( matchclass=None, startnode=None ):
  21. """
  22. In the simplest way possible, this function will go upstream and find
  23. the first node matching the specified class.
  24. """
  25. if matchclass == None:
  26. return None
  27. #
  28. if startnode == None:
  29. return None
  30. #
  31. if startnode.Class() == matchclass:
  32. return startnode
  33. else:
  34. return find_upstream_node( matchclass=matchclass, startnode=startnode.input( 0 ) )
  35. #
  36. #
  37. def make_write_from_read():
  38. """
  39. This method will assist automated creation of Write-nodes, using the filename of
  40. upstream Read-nodes.
  41. Typical scenario:
  42. 1. Drop in a bunch of still images.
  43. 2. Foreach image add some, for example, Grade-nodes and fix a good look.
  44. 3. Now select all grade-nodes and run this script.
  45. 4. The script will look for an upstream Read-node and use that filename
  46. for creation of write nodes. The panel that presents itself will allow
  47. you to modify that filename or path.
  48. """
  49. if len( nuke.selectedNodes() ) < 1:
  50. return
  51. #
  52. readNodeLut = {}
  53. # Build Lookup for each selected node.
  54. for tmpNode in nuke.selectedNodes():
  55. readNode = find_upstream_node( matchclass="Read", startnode=tmpNode )
  56. if readNode:
  57. readNodeLut[tmpNode] = readNode
  58. #
  59. #
  60. # autocrop true
  61. if len( readNodeLut ) < 1:
  62. return
  63. #
  64. formatList = []
  65. formatList.append( "nochange" )
  66. formatList.append( "jpeg" )
  67. formatList.append( "tiff" )
  68. formatList.append( "exr" )
  69. formatList.append( "dpx" )
  70. formatList.append( "png" )
  71. formatList.append( "tga" )
  72. tiffDatatypeList = []
  73. tiffDatatypeList.append( '"16 bit"' )
  74. tiffDatatypeList.append( '"8 bit"' )
  75. tiffDatatypeList.append( '"32 bit float"' )
  76. tiffCompressionList = []
  77. tiffCompressionList.append( '"LZW"' )
  78. tiffCompressionList.append( '"none"' )
  79. tiffCompressionList.append( '"Deflate"' )
  80. tiffCompressionList.append( '"PackBits"' )
  81. tgaCompressionList = []
  82. tgaCompressionList.append( '"none"' )
  83. tgaCompressionList.append( '"RLE"' )
  84. exrDatatypeList = []
  85. exrDatatypeList.append( '"16 bit half"' )
  86. exrDatatypeList.append( '"32 bit float"' )
  87. exrCompressionList = []
  88. exrCompressionList.append( '"Zip (1 scanline)"' ) # cg and lots of black
  89. exrCompressionList.append( '"Zip (16 scanlines)"' ) # cg and lots of black
  90. exrCompressionList.append( '"PIZ Wavelet (32 scanlines)"' ) # good grainy images
  91. exrCompressionList.append( '"RLE"' )
  92. exrCompressionList.append( '"B44"' )
  93. exrCompressionList.append( '"none"' )
  94. jpegQualityList = []
  95. jpegQualityList.append( "1.0" )
  96. jpegQualityList.append( "0.9" )
  97. jpegQualityList.append( "0.8" )
  98. jpegQualityList.append( "0.7" )
  99. jpegQualityList.append( "0.6" )
  100. jpegQualityList.append( "0.5" )
  101. jpegQualityList.append( "0.4" )
  102. jpegQualityList.append( "0.3" )
  103. jpegQualityList.append( "0.2" )
  104. jpegQualityList.append( "0.1" )
  105. formatPulldown = " ".join( formatList )
  106. jpegQualityPulldown = " ".join( jpegQualityList )
  107. tiffDatatypePulldown = " ".join( tiffDatatypeList )
  108. tiffCompressionPulldown = " ".join( tiffCompressionList )
  109. tgaCompressionPulldown = " ".join( tgaCompressionList )
  110. exrDatatypePulldown = " ".join( exrDatatypeList )
  111. exrCompressionPulldown = " ".join( exrCompressionList )
  112. addPrefix = ""
  113. addPostfix = ""
  114. addPath = ""
  115. #autocrop = ""
  116. addPathHandle = "Path add-on (relative or absolute):"
  117. addPrefixHandle = "Prefix (added in front of the filename):"
  118. addPostfixHandle = "Suffix (inserted before the extension):"
  119. formatPulldownHandle = "Format:"
  120. jpegQualityPulldownHandle = "Jpeg Quality:"
  121. tiffDatatypePulldownHandle = "TIFF Datatype:"
  122. tiffCompressionPulldownHandle = "TIFF Compression:"
  123. tgaCompressionPulldownHandle = "TGA Compression:"
  124. exrDatatypePulldownHandle = "EXR Datatype:"
  125. exrCompressionPulldownHandle = "EXR Compression:"
  126. exrAutocropHandle = "Autocrop -> DataWindow"
  127. p = nuke.Panel("Make Write of Read")
  128. p.addSingleLineInput(addPathHandle, addPath )
  129. p.addSingleLineInput(addPrefixHandle, addPrefix )
  130. p.addSingleLineInput(addPostfixHandle, addPostfix )
  131. p.addEnumerationPulldown(formatPulldownHandle, formatPulldown )
  132. p.addEnumerationPulldown(jpegQualityPulldownHandle, jpegQualityPulldown )
  133. p.addEnumerationPulldown(tiffDatatypePulldownHandle, tiffDatatypePulldown )
  134. p.addEnumerationPulldown(tiffCompressionPulldownHandle, tiffCompressionPulldown )
  135. p.addEnumerationPulldown(tgaCompressionPulldownHandle, tgaCompressionPulldown )
  136. p.addEnumerationPulldown(exrDatatypePulldownHandle, exrDatatypePulldown )
  137. p.addEnumerationPulldown(exrCompressionPulldownHandle, exrCompressionPulldown )
  138. p.addBooleanCheckBox(exrAutocropHandle, 1 )
  139. p.addButton("Cancel")
  140. p.addButton("OK")
  141. result = p.show()
  142. #if ok is clicked, panel will return 1 otherwise 0
  143. if result:
  144. pass
  145. else:
  146. return None
  147. #
  148. # Get Values from enumeration objects.
  149. selectedFormat = p.value(formatPulldownHandle)
  150. selectedJpegQuality = p.value(jpegQualityPulldownHandle)
  151. selectedTiffDatatype = p.value(tiffDatatypePulldownHandle)
  152. selectedTiffCompression = p.value(tiffCompressionPulldownHandle)
  153. selectedTgaCompression = p.value(tgaCompressionPulldownHandle)
  154. selectedExrDatatype = p.value(exrDatatypePulldownHandle)
  155. selectedExrCompression = p.value(exrCompressionPulldownHandle)
  156. selectedAutocrop = p.value(exrAutocropHandle)
  157. addPath = p.value(addPathHandle)
  158. addPrefix = p.value(addPrefixHandle)
  159. addPostfix = p.value(addPostfixHandle)
  160. if ( addPath == "" ) and ( addPrefix == "" ) and ( addPostfix == "" ):
  161. if selectedFormat == "nochange":
  162. result = nuke.ask( "Warning, your write nodes will have the same filename as\nyour Read-nodes.\n\n Are you sure that this is what you want?" )
  163. else:
  164. result = nuke.ask( "Warning, you only changed the file format.\n\nYour write nodes MIGHT have the same filename as\nyour Read-nodes.\n\n Are you sure that this is what you want?" )
  165. #
  166. if result:
  167. pass
  168. else:
  169. return None #your script will exit now
  170. #
  171. #
  172. # Deselect all
  173. for tmpNode in nuke.selectedNodes():
  174. tmpNode['selected'].setValue(False)
  175. selectThese = []
  176. for ( tmpNode, readNode ) in readNodeLut.iteritems():
  177. tmpNode['selected'].setValue(True)
  178. #originalFilename = readNode["file"]
  179. originalFilename = nuke.filename( readNode )
  180. ( basepath, filename ) = os.path.split( originalFilename )
  181. ( basefile, extension ) = os.path.splitext( filename )
  182. if selectedFormat == "nochange":
  183. tmpExt = extension.lstrip( '.' )
  184. if ( tmpExt.lower() == "jpg" ) or ( tmpExt.lower() == "jpeg" ):
  185. type = "jpeg"
  186. elif ( tmpExt.lower() == "tif" ) or ( tmpExt.lower() == "tiff" ) or ( tmpExt.lower() == "tif16" ):
  187. type = "tiff"
  188. else:
  189. type = tmpExt
  190. #
  191. #
  192. else:
  193. type = selectedFormat
  194. extension = "." + type
  195. if extension == ".jpeg":
  196. type = "jpeg"
  197. extension = ".jpg"
  198. elif extension == ".tiff":
  199. type = "tiff"
  200. extension = ".tif"
  201. elif extension == ".tga":
  202. type = "tga"
  203. extension = ".tga"
  204. #
  205. #
  206. normalizedBasepath = os.path.normpath( basepath )
  207. normalizedAddPath = os.path.normpath( addPath )
  208. #print "normalizedBasepath", normalizedBasepath
  209. #print "normalizedAddPath", normalizedAddPath
  210. # This will also take care of absolute paths.
  211. newFilename = os.path.join( normalizedBasepath, normalizedAddPath )
  212. # Remove any ".." and similar.
  213. newFilename = os.path.normpath( newFilename )
  214. newFilename = os.path.join( newFilename, addPrefix + basefile + addPostfix + extension ).replace( "\\", "/" )
  215. wn = nuke.createNode("Write", "", inpanel = False )
  216. wn['selected'].setValue(False)
  217. wn['file'].setValue( newFilename )
  218. wn['file_type'].setValue( type )
  219. if type == "jpeg":
  220. wn['_jpeg_quality'].setValue( float( selectedJpegQuality ) )
  221. wn['channels'].setValue("rgb")
  222. elif type == "tiff":
  223. wn['datatype'].setValue( selectedTiffDatatype )
  224. wn['compression'].setValue( selectedTiffCompression )
  225. elif type == "exr":
  226. wn['datatype'].setValue( selectedExrDatatype )
  227. wn['compression'].setValue( selectedExrCompression )
  228. wn['autocrop'].setValue( selectedAutocrop )
  229. wn['channels'].setValue("all")
  230. elif type == "dpx":
  231. wn['channels'].setValue("rgb")
  232. elif type == "tga":
  233. wn['compression'].setValue(selectedTgaCompression)
  234. #
  235. wn.setInput( 0, tmpNode )
  236. selectThese.append( wn )
  237. #
  238. for tmpNode in selectThese:
  239. tmpNode['selected'].setValue( True )
  240. #
  241. #