Package nukescripts :: Module readviewscheck
[hide private]
[frames] | no frames]

Source Code for Module nukescripts.readviewscheck

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ Check for multiple views in files when a read node is created, by 
  4  looking for a VIEW_NAMES entry in the node's metadata. 
  5  Most file types won't specify views but EXR/SXR and potentially other 
  6  files may do. 
  7  Registers for callbacks when a Read node is created, or its 'file' knob 
  8  is changed.  If there are multiple views, and they do not exist on the 
  9  root node, the user is asked if they should be created. 
 10  """ 
 11   
 12  import nuke 
 13  from PySide2.QtCore import QTimer 
 14  from PySide2.QtWidgets import QApplication, QMessageBox 
 15   
 16  # Global for storing when the user says no 
 17  UserAlreadySaidNo = False 
 18   
19 -def createViews(views):
20 """ Add the views in a list to the root node. """ 21 for view in views: 22 # Set "left" and "right" colours to match "setup views for stereo" behaviour 23 if view == "left": 24 nuke.root().addView(view, "#FF0000") 25 elif view == "right": 26 nuke.root().addView(view, "#00FF00") 27 else: 28 nuke.root().addView(view)
29 30
31 -def getViews(read):
32 """ Attempt to get the views from a read node's metadata. Returns an 33 empty list if no views were found or if the node is disabled. """ 34 35 # disabled nodes return None when calling metadata() 36 if read['disable'].value(): 37 return [] 38 39 readMetadata = read.metadata() 40 if type(readMetadata) is not dict: 41 return [] 42 43 # Try to read the expected key. Catch KeyError and return an empty list if 44 # not present 45 try: 46 # If present, the metadata value is a list of view names separated by 47 # newlines. 48 views = readMetadata[nuke.VIEW_NAMES].split('\n') 49 50 # Now exclude any views that are wrapped in [], which indicate they're generic views rather 51 # than explicitly specified named views (e.g. we're reading from a multitrack QuickTime file 52 # and hence they're just some placeholder names generated by the reader). 53 # rick: This shouldn't be necessary when we support view-to-track mapping for QuickTimes, etc. 54 trueViews = [] 55 for view in views: 56 if not (view.startswith('[') and view.endswith(']')): 57 trueViews += [view] 58 return trueViews 59 except KeyError: 60 return []
61 62
63 -def checkReadNodeViews(read):
64 """ Check if a read has multiple views, and if so, ask the user if they 65 want to add them to the root node. """ 66 global UserAlreadySaidNo 67 # Check we have a nuke read node rather than a timeline read node as the view checks 68 # for timeline read nodes are carried out in MediaSearch::promptUserToCreateViews() 69 # Because this callback happens asynchronously, it is possible that when called, the 70 # node no longer exists. An exception will be thrown in this case. 71 try: 72 isNukeReadNode = (read.rootNode() is nuke.root()) 73 except: 74 isNukeReadNode = False 75 76 if not UserAlreadySaidNo and isNukeReadNode: 77 views = getViews(read) 78 if views: 79 # Find the views in the read that do not exist on the Root node and if 80 # there are any, ask the user what to do. 81 rootViews = nuke.views() 82 missingViews = [ view for view in views if view not in rootViews ] 83 84 if missingViews: 85 userChoice = nuke.showCreateViewsDialog(missingViews) 86 if userChoice is nuke.DONT_CREATE_VIEWS: 87 UserAlreadySaidNo = True 88 elif userChoice is nuke.REPLACE_VIEWS: 89 viewsToDelete = [ view for view in rootViews if view not in views ] 90 # Create all views in the clip 91 createViews(views) 92 # Remove the views that are not in views 93 for existingView in viewsToDelete: 94 nuke.root().deleteView(existingView) 95 elif userChoice is nuke.ADD_VIEWS: 96 # Create only the missing views 97 createViews(missingViews)
98 99
100 -def onReadNodeCreated():
101 """ Callback when a Read node is created. Note that the knob values 102 don't seem to be set when this callback occurs. Defer the check with 103 a QTimer, which will cause the views check to be done when the Qt event 104 loop next sends events. 105 """ 106 read = nuke.thisNode() 107 QTimer.singleShot(0, lambda: checkReadNodeViews(read))
108 109
110 -def onReadNodeKnobChanged():
111 """ Callback when a Read node knob changes. If it's the file knob, 112 check for multi views. 113 """ 114 if nuke.thisKnob().name() == "file": 115 checkReadNodeViews(nuke.thisNode())
116 117 118 # Register the callbacks 119 nuke.addKnobChanged(onReadNodeKnobChanged, nodeClass="Read") 120 nuke.addOnUserCreate(onReadNodeCreated, nodeClass="Read") 121