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.

GrayAutoBackdrop.py 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. # Copyright (c) 2009 The Foundry Visionmongers Ltd. All Rights Reserved.
  2. # Edit by Max van Leeuwen - maxvanleeuwen.com - 1.2
  3. # PREFERENCES FOR DEFAULT SETTINGS:
  4. # sticky note default label size
  5. defaultStickyLabelSize = '50'
  6. # sticky note default color
  7. defaultStickyColor = 3435954431
  8. # change colors of the backdrops that are within the newly created one
  9. defaultUpdateBackdrops = True
  10. # color for backdrop (stacked backdrops will get darker)
  11. startingColor = 1179010815
  12. # backdrop colors to never change (photoshop breakout layers)
  13. ignoreColors = [2829621248, 1751668736]
  14. # backdrop boundaries scaling
  15. bdSize = 3
  16. ############################################
  17. import nuke, random
  18. import colorsys
  19. # make every stacked backdrop slightly darker
  20. def darker(levels):
  21. newColor = startingColor
  22. for i in range( int( abs(levels) ) ):
  23. RGB = [(0xFF & newColor >> i) / 255.0 for i in [24,16,8]]
  24. HSV = colorsys.rgb_to_hsv(RGB[0],RGB[1],RGB[2])
  25. newHSV = [HSV[0], HSV[1], HSV[2] * .85]
  26. newRGB = colorsys.hsv_to_rgb(newHSV[0],newHSV[1],newHSV[2])
  27. newColor = int('%02x%02x%02x%02x' % (round(newRGB[0]*255),round(newRGB[1]*255),round(newRGB[2]*255),255),16)
  28. return newColor
  29. def nodeIsInside(node, backdropNode):
  30. """Returns true if node geometry is inside backdropNode otherwise returns false"""
  31. topLeftNode = [node.xpos(), node.ypos()]
  32. topLeftBackDrop = [backdropNode.xpos(), backdropNode.ypos()]
  33. bottomRightNode = [node.xpos() + node.screenWidth(), node.ypos() + node.screenHeight()]
  34. bottomRightBackdrop = [backdropNode.xpos() + backdropNode.screenWidth(), backdropNode.ypos() + backdropNode.screenHeight()]
  35. topLeft = ( topLeftNode[0] >= topLeftBackDrop[0] ) and ( topLeftNode[1] >= topLeftBackDrop[1] )
  36. bottomRight = ( bottomRightNode[0] <= bottomRightBackdrop[0] ) and ( bottomRightNode[1] <= bottomRightBackdrop[1] )
  37. return topLeft and bottomRight
  38. # function can be called with custom default variables
  39. def GrayAutoBackdrop():
  40. global defaultStickyLabelSize
  41. global defaultStickyColor
  42. global defaultUpdateBackdrops
  43. bdUpdateBooleantext = 'update included backdrops?'
  44. '''
  45. Automatically puts a backdrop behind the selected nodes.
  46. The backdrop will be just big enough to fit all the select nodes in, with room
  47. at the top for some text in a large font.
  48. '''
  49. # check if nodes are selected
  50. selNodes = nuke.selectedNodes()
  51. if selNodes:
  52. # panel
  53. p = nuke.Panel('backdrop')
  54. p.addSingleLineInput('label', '')
  55. p.addBooleanCheckBox(bdUpdateBooleantext, defaultUpdateBackdrops)
  56. panelObj = p.show()
  57. if panelObj:
  58. # calculate bounds for the backdrop node.
  59. bdX = min([node.xpos() for node in selNodes])
  60. bdY = min([node.ypos() for node in selNodes])
  61. bdW = max([node.xpos() + node.screenWidth() for node in selNodes]) - bdX
  62. bdH = max([node.ypos() + node.screenHeight() for node in selNodes]) - bdY
  63. # bigger boundaries if node area is bigger
  64. boundsMult = 10 + (bdW + bdH) * (bdSize/100)
  65. zOrder = 0
  66. defaultUpdateBackdrops = p.value(bdUpdateBooleantext)
  67. noBackdropNodes = False
  68. if defaultUpdateBackdrops:
  69. selectedBackdropNodes = nuke.selectedNodes("BackdropNode")
  70. # if there are backdropNodes selected, put the new one at the lowest level and all others at their own level + 1
  71. if len(selectedBackdropNodes):
  72. # placeholders
  73. lowest = 99999
  74. offs = 0
  75. for sBD in selectedBackdropNodes:
  76. currVal = sBD['z_order'].value()
  77. lowest = min(lowest, currVal)
  78. # all backdrops must be => 0
  79. if lowest < 0:
  80. offs = abs(lowest)
  81. lowest = 0
  82. for sBD in selectedBackdropNodes:
  83. currVal = sBD['z_order'].value()
  84. newZ = currVal + 1 + offs
  85. sBD['z_order'].setValue(newZ)
  86. if not sBD['tile_color'].value() in ignoreColors:
  87. sBD['tile_color'].setValue(darker(newZ))
  88. zOrder = lowest
  89. else:
  90. noBackdropNodes = True
  91. if (not defaultUpdateBackdrops) or noBackdropNodes:
  92. # else (no backdrop in selection) find the nearest backdrop if exists and set the new one in front of it
  93. nonSelectedBackdropNodes = nuke.allNodes("BackdropNode")
  94. for nonBackdrop in selNodes:
  95. for backdrop in nonSelectedBackdropNodes:
  96. if nodeIsInside( nonBackdrop, backdrop ):
  97. zOrder = max(zOrder, backdrop.knob("z_order").value() + 1 )
  98. # Expand the bounds to leave a border, relative to zoom size. Elements are offsets for left, top, right and bottom edges respectively. Extra top height if larger label.
  99. left, top, right, bottom = (-10 * boundsMult, -80 - 10 * boundsMult, 10 * boundsMult, 10 * boundsMult)
  100. bdX += left
  101. bdY += top
  102. bdW += (right - left)
  103. bdH += (bottom - top)
  104. labelstr = p.value('label')
  105. n = nuke.nodes.BackdropNode(xpos = bdX,
  106. bdwidth = bdW,
  107. ypos = bdY,
  108. bdheight = bdH,
  109. note_font_size = 100,
  110. tile_color = darker(zOrder if defaultUpdateBackdrops else 0),
  111. z_order = zOrder if defaultUpdateBackdrops else 0,
  112. label = labelstr)
  113. # revert to previous selection + this backdrop
  114. n['selected'].setValue(True)
  115. for node in selNodes:
  116. node['selected'].setValue(True)
  117. return n
  118. else:
  119. pass
  120. # if no nodes are selected, make sticky note
  121. else:
  122. # panel
  123. p = nuke.Panel('stickynote')
  124. p.addSingleLineInput('label', '')
  125. p.addSingleLineInput('label size', defaultStickyLabelSize)
  126. p.addButton('cancel')
  127. p.addButton('done')
  128. p.addButton('color')
  129. # show panel
  130. panelObj = p.show()
  131. # if user did not cancel panel or leave label empty
  132. if panelObj:
  133. # get color form different panel, because the RGBChip in nuke's panel is broken
  134. if(panelObj == 2):
  135. colObj = nuke.getColor(defaultStickyColor)
  136. if colObj:
  137. defaultStickyColor = colObj
  138. # try to get and set label size
  139. try:
  140. l = int(p.value('label size'))
  141. defaultStickyLabelSize = l
  142. except:
  143. pass
  144. # make stickynote, show panel if the label was empty (the user might want to type multiline text)
  145. n = nuke.createNode("StickyNote", inpanel=(p.value('label') == ''))
  146. n['note_font_size'].setValue(defaultStickyLabelSize)
  147. n['label'].setValue(p.value('label'))
  148. n['tile_color'].setValue(defaultStickyColor)
  149. n.setXpos(n.xpos() - round(n.screenWidth()/2))
  150. n.setYpos(n.ypos() + round(n.screenHeight()/2))
  151. # autostart (if not imported)
  152. if __name__ == "__main__":
  153. GrayAutoBackdrop()