nukescripts.trackerlinkingdialog

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

# Source Code for Module nukescripts.trackerlinkingdialog

      1  import nuke
      2  import nukescripts
      3
      4  ##############################################################################
      5  # A quick-n-dirty storage of "last values" for knobs that we want to appear
      6  # with the value they were assigned the last time the dialog was open during
      7  # this GUI session.
      8
      9  _gLastState = {}
     10
     11 -def _getLastState( knob, defaultValue=None ):
     12    """Return the given knob's stored last state value.
     13    If none exists, defaultValue is returned.
     14    Values are stored in a dict referenced by knob name, so names must be unique!"""
     15    global _gLastState
     16    if _gLastState.has_key( knob.name() ):
     17      return _gLastState[knob.name()]
     18    else:
     19      return defaultValue
     20
     21 -def _setLastState( knob ):
     22    """Store the knob's current value as the 'last state' for the next time the dialog is opened.
     23    Values are stored in a dict referenced by knob name, so names must be unique!"""
     24    global _gLastState
     25    _gLastState[knob.name()] = knob.value()
     26
     27
     28  ##############################################################################
     29  # LinkToTrack Panel
     30  # This panel offers the user a selection of Tracker nodes in the project and
     31  # returns an expression referencing either the Tracker's 'translate' knob or
     32  # computing the average value of the selected track points on the node.
     33
     34 -class LinkToTrackPanel( nukescripts.PythonPanel ):
     35 -  def __init__( self, groupContext ):
     36      nukescripts.PythonPanel.__init__( self, "Link to Tracker", "uk.co.thefoundry.LinkToTrackPanel" )
     37
     38      # Show a list of trackers in the project.
     39      trackers = []
     40      with nuke.toNode(groupContext):
     41        for n in nuke.allNodes():
     42          if n.linkableKnobs(nuke.KnobType.eXYKnob):
     43            trackers.append( n.name() )
     44      self._tracker = nuke.Enumeration_Knob( "trackers", "tracker node", trackers )
     45      self._tracker.setTooltip( "The Tracker node to link to." )
     46      self._tracker.setValue( _getLastState( self._tracker, trackers[0] ) )
     47      self.addKnob( self._tracker )
     48
     49      # Choice of linking to the translate on the tracker or to track point positions.
     50      self._link_to = nuke.Enumeration_Knob( "link_to", "link to", ["position", "translate", "translate as offset"] )
     51      self._link_to.setValue( _getLastState( self._link_to, 'translate' ) )
     52      self._link_to.setTooltip( "Choose whether to link to the translation computed in the Tracker's Transform tab or to a specific track point position. If multiple track points are chosen they will be averaged." )
     53      self.addKnob( self._link_to )
     54      self._link_to.setFlag( nuke.ENDLINE )
     55
     56      # Display check boxes for selection of which track points should be linked.
     57      # If more than one is selected the expression is set to average them.
     58      # Tracker nodes are currently limited to 4 points. If that changes we will need
     59      # to be smarter here and create the right number of booleans for the currently
     60      # selected node (and update when the node selection is changed).
     61      self._track_points = []
     62      for t in xrange(1,5):
     63        knobname = 'track'+str(t)
     64        point = nuke.Boolean_Knob( knobname, knobname )
     65        # By default the first point is enabled but not the rest,
     66        # unless there is previous session state to restore.
     67        point.setValue( _getLastState( point, (t==1) ) )
     68        point.setTooltip( "Use this track point when linking to 'position'." )
     69        self._track_points.append( point )
     70        self.addKnob( point )
     71
     72      self._updatePointsEnabled()
     73
     74      # Show the expression that's going to set in case user wants to tweak or
     75      # copy it before closing the dialog.
     76      self._expression = nuke.EvalString_Knob( "expression" )
     77      self._expression.setTooltip( "This is the expression that will be applied. You can edit it before closing the dialog but changing settings on this panel will rebuild it, losing your changes." )
     78      self.addKnob( self._expression )
     79      self._updateExpression()
     80
     81
     82 -  def _updateExpression(self):
     83      """Update the expression to reflect the current settings."""
     84      if self._link_to.value() == 'translate':
     85        self._expression.setValue( self._tracker.value() + ".translate" )
     86      elif self._link_to.value() == 'translate as offset':
     87        self._expression.setValue( "curve + " + self._tracker.value() + ".translate" )
     88      else:
     89        pointCount = 0
     90        expr = " + ".join([self._tracker.value() + "." + point.name() for point in self._track_points if point.value()])
     91        pointCount = sum( (1 for point in self._track_points if point.value()) )
     92        if pointCount > 1:
     93          expr = "(" + expr + ")/" + str(pointCount)
     94        self._expression.setValue( expr )
     95
     96
     97 -  def _updatePointsEnabled(self):
     98      """Enable the track point bools when linking to position; disable otherwise."""
     99      use_points = ( self._link_to.value() == 'position' )
    100      for point in self._track_points:
    101        point.setEnabled( use_points )
    102
    103
    104 -  def getExpression(self):
    105      """Return the expression field value."""
    106      return self._expression.value()
    107
    108
    109 -  def knobChanged( self, knob ):
    110      _setLastState( knob )
    111
    112      # If expression changes, don't try to update and possibly trash it.
    113      if knob == self._expression:
    114        return
    115
    116      self._updateExpression()
    117      if knob == self._link_to:
    118        self._updatePointsEnabled()
    119      elif knob == self._tracker:
    120        global _gLastTracker
    121        _gLastTracker = knob.value()
    122
    123 -  def addToPane( self ):
    124      nukescripts.PythonPanel.addToPane( self, pane=nuke.thisPane() )
    125
    126
    127
    128 -def trackerlinkingdialog(groupContext):
    129    d = LinkToTrackPanel(groupContext)
    130    if d.showModalDialog() == True:
    131      return d.getExpression()
    132