def useFixedVolume(self, volume):

    # TODO store original orientation?
    axialVolume = self.reorientVolumeToAxial(volume)
    self.axialFixedVolume = axialVolume

    widget = slicer.modules.SteeredPolyAffineRegistrationWidget

    self.fixedImageCL = ImageCL(self.preferredDeviceType)
    self.fixedImageCL.fromVolume(axialVolume)
    self.fixedImageCL.normalize()
  def useMovingVolume(self, volume):

    # TODO store original orientation?
    axialVolume = self.reorientVolumeToAxial(volume)
    self.axialMovingVolume = axialVolume

    self.movingImageCL = ImageCL(self.preferredDeviceType)
    self.movingImageCL.fromVolume(axialVolume)
    self.movingImageCL.normalize()

    self.origMovingImageCL = self.movingImageCL
  def initOutputVolume(self, outputVolume):
    # NOTE: Reuse old result?
    # TODO: need to store old deformation for this to work, for now reset everything
    widget = slicer.modules.SteeredPolyAffineRegistrationWidget

    if outputVolume is None:
      vl = slicer.modules.volumes.logic()
      # Use reoriented moving volume
      outputVolume = vl.CloneVolume(slicer.mrmlScene, self.axialMovingVolume, "steered-warped")
      widget.outputSelector.setCurrentNode(outputVolume)
    else:
      outputImage = vtk.vtkImageData()
      outputImage.DeepCopy(self.axialMovingVolume.GetImageData())
      outputVolume.SetAndObserveImageData(outputImage)
      #TODO reuse deformation

    self.outputImageCL = ImageCL(self.preferredDeviceType)
    self.outputImageCL.fromVolume(outputVolume)
    self.outputImageCL.normalize()
        
    # Force update of gradient magnitude image
    self.updateOutputVolume( self.outputImageCL )
class SteeredPolyAffineRegistrationLogic(object):
#TODO
  """ Implement a template matching optimizer that is
  integrated with the slicer main loop.
  """

  def __init__(self):
    self.interval = 1000
    self.timer = None

    # parameter defaults
    self.numberAffines = 1
    self.drawIterations = 1
    self.polyAffineRadius = 10.0

    # TODO
    #self.transform = ?

    # optimizer state variables
    self.iteration = 0

    self.interaction = False

    self.steerMode = "rotate"

    self.position = []
    self.paintCoordinates = []

    self.lastEventPosition = [0.0, 0.0, 0.0]
    self.startEventPosition = [0.0, 0.0, 0.0]
    
    # Queue containing info on steering action events, tuples of
    # (Mtime, action, xy0, RAS0, xy1, RAS1, sliceWidget)
    # Draw added poly affine correction? Fold it immediately?
    self.actionQueue = Queue.Queue()

    self.lineStartXY = (0, 0, 0)
    self.lineEndXY = (0, 0, 0)
    
    self.lineStartRAS = [0.0, 0.0, 0.0]
    self.lineEndRAS = [0.0, 0.0, 0.0]

    print("Reload")

    self.actionState = "idle"
    self.interactorObserverTags = []
    
    self.styleObserverTags = []
    self.sliceWidgetsPerStyle = {}

    self.nodeIndexPerStyle = {}
    self.sliceNodePerStyle = {}
    
    self.lastDrawMTime = 0
    self.lastDrawSliceWidget = None

    self.linesActor = vtk.vtkActor()
    self.linesMapper = vtk.vtkPolyDataMapper()
    self.linesGlyph = vtk.vtkGlyph3D()

    self.roiActor = vtk.vtkActor()
    self.roiMapper = vtk.vtkPolyDataMapper()
    self.roiGlyph = vtk.vtkGlyph3D()

    self.linesActor.GetProperty().SetOpacity(0.5)
    self.linesActor.GetProperty().SetColor([0.1, 0.8, 0.1])

    self.roiActor.GetProperty().SetOpacity(0.5)
    self.roiActor.GetProperty().SetColor([0.1, 0.1, 0.9])

    self.preferredDeviceType = "GPU"
    
  def __del__(self):
  
    # TODO
    # Clean up, delete line in render window
    layoutManager = slicer.app.layoutManager()
    sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode')
    for nodeIndex in xrange(sliceNodeCount):
      # find the widget for each node in scene
      sliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex, 'vtkMRMLSliceNode')
      sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName())
      
      if sliceWidget:
        renwin = sliceWidget.sliceView().renderWindow()
        rencol = renwin.GetRenderers()
        if rencol.GetNumberOfItems() == 2:
          rencol.GetItemAsObject(1).RemoveActor(self.linesActor)

  def reorientVolumeToAxial(self, volume):
    nodeName = slicer.mrmlScene.GetUniqueNameByString(volume.GetName())

    vl = slicer.modules.volumes.logic()
    axialVolume = vl.CloneVolume(slicer.mrmlScene, volume, nodeName)
    axialVolume.SetName(nodeName)

    slicer.mrmlScene.AddNode(axialVolume)

    cliparams = {}
    cliparams["orientation"] = "Axial"
    cliparams["inputVolume1"] = volume.GetID()
    cliparams["outputVolume"] = axialVolume.GetID()

    print "Axial reorientation of " + volume.GetID() + " to " + axialVolume.GetID()

    slicer.cli.run(slicer.modules.orientscalarvolume, None,
      cliparams, wait_for_completion=True)

    return axialVolume

  def useFixedVolume(self, volume):

    # TODO store original orientation?
    axialVolume = self.reorientVolumeToAxial(volume)
    self.axialFixedVolume = axialVolume

    widget = slicer.modules.SteeredPolyAffineRegistrationWidget

    self.fixedImageCL = ImageCL(self.preferredDeviceType)
    self.fixedImageCL.fromVolume(axialVolume)
    self.fixedImageCL.normalize()

  def useMovingVolume(self, volume):

    # TODO store original orientation?
    axialVolume = self.reorientVolumeToAxial(volume)
    self.axialMovingVolume = axialVolume

    self.movingImageCL = ImageCL(self.preferredDeviceType)
    self.movingImageCL.fromVolume(axialVolume)
    self.movingImageCL.normalize()

    self.origMovingImageCL = self.movingImageCL

  def initOutputVolume(self, outputVolume):
    # NOTE: Reuse old result?
    # TODO: need to store old deformation for this to work, for now reset everything
    widget = slicer.modules.SteeredPolyAffineRegistrationWidget

    if outputVolume is None:
      vl = slicer.modules.volumes.logic()
      # Use reoriented moving volume
      outputVolume = vl.CloneVolume(slicer.mrmlScene, self.axialMovingVolume, "steered-warped")
      widget.outputSelector.setCurrentNode(outputVolume)
    else:
      outputImage = vtk.vtkImageData()
      outputImage.DeepCopy(self.axialMovingVolume.GetImageData())
      outputVolume.SetAndObserveImageData(outputImage)
      #TODO reuse deformation

    self.outputImageCL = ImageCL(self.preferredDeviceType)
    self.outputImageCL.fromVolume(outputVolume)
    self.outputImageCL.normalize()
        
    # Force update of gradient magnitude image
    self.updateOutputVolume( self.outputImageCL )

  def updateOutputVolume(self, imgcl):

    widget = slicer.modules.SteeredPolyAffineRegistrationWidget

    outputVolume = widget.outputSelector.currentNode()  

    """
    displayShape = self.fixedImageCL.shape
    for dim in xrange(3):
      displayShape[dim] = min(
        displayShape[dim], widget.displayGridSpinBoxes[dim].value)

    imgcl_gridded = imgcl.resample(displayShape)
    imgcl_gridded.copyToVolume(outputVolume)

    # TODO: need ratios / mapping between screen and grad mag image
    # displayGridRatios, warpGridRatios
    """

    vtkimage = imgcl.toVTKImage()

    #TODO sync origin
  
    #castf = vtk.vtkImageCast()
    #castf.SetOutputScalarTypeToFloat()
    #castf.SetInput(vtkimage)
    #castf.Update()
  
    #outputVolume.GetImageData().GetPointData().SetScalars( castf.GetOutput().GetPointData().GetScalars() )

    oldimage = outputVolume.GetImageData()

    outputVolume.SetAndObserveImageData(vtkimage)
    #outputVolume.GetImageData().GetPointData().SetScalars( vtkimage.GetPointData().GetScalars() )
    #outputVolume.GetImageData().GetPointData().GetScalars().Modified()
    #outputVolume.GetImageData().Modified()
    #outputVolume.Modified()

  def startSteeredRegistration(self):

    widget= slicer.modules.SteeredPolyAffineRegistrationWidget

    fixedVolume = widget.fixedSelector.currentNode()  
    movingVolume = widget.movingSelector.currentNode()  
    outputVolume = widget.outputSelector.currentNode()  

    #print(self.identity)            
    self.removeObservers()
    # get new slice nodes
    layoutManager = slicer.app.layoutManager()
    sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode')
    for nodeIndex in xrange(sliceNodeCount):
      # find the widget for each node in scene
      sliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex, 'vtkMRMLSliceNode')
      sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName())
      
      if sliceWidget:
          
        # add observers and keep track of tags
        style = sliceWidget.sliceView().interactorStyle()
        self.interactor = style.GetInteractor()
        self.sliceWidgetsPerStyle[self.interactor] = sliceWidget
        self.nodeIndexPerStyle[self.interactor] = nodeIndex
        self.sliceNodePerStyle[self.interactor] = sliceNode
        
        events = ( "LeftButtonPressEvent","LeftButtonReleaseEvent","MouseMoveEvent", "KeyPressEvent","EnterEvent", "LeaveEvent" )
        for event in events:
          tag = self.interactor.AddObserver(event, self.processEvent, 1.0)
          self.interactorObserverTags.append(tag)
      
    compositeNodeDict = slicer.util.getNodes('vtkMRMLSliceCompositeNode*')

    sortedKeys = sorted(compositeNodeDict.iterkeys())

    for i in xrange(3):
      compositeNode = compositeNodeDict[sortedKeys[i]]
      compositeNode.SetBackgroundVolumeID(fixedVolume.GetID())
      compositeNode.SetForegroundVolumeID(outputVolume.GetID())
      compositeNode.SetForegroundOpacity(0.0)
      compositeNode.LinkedControlOn()
    for i in xrange(3,6):
      compositeNode = compositeNodeDict[sortedKeys[i]]
      compositeNode.SetBackgroundVolumeID(fixedVolume.GetID())
      compositeNode.SetForegroundVolumeID(outputVolume.GetID())
      compositeNode.SetForegroundOpacity(1.0)
      compositeNode.LinkedControlOn()

    #compositeNodes.values()[0].LinkedControlOn()
    yellowWidget = layoutManager.sliceWidget('Yellow')
      
    # Set all view orientation to axial
    #sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode')
    #for nodeIndex in xrange(sliceNodeCount):
    #  sliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex, 'vtkMRMLSliceNode')
    #  sliceNode.SetOrientationToAxial()
      
    applicationLogic = slicer.app.applicationLogic()
    applicationLogic.FitSliceToAll()
    
    # Initialize poly affine
    self.polyAffine = PolyAffineCL(self.fixedImageCL, self.movingImageCL)
    self.polyAffine.create_identity(self.numberAffines)
    # TODO: use radius info from GUI
    self.polyAffine.optimize_setup()

    self.registrationIterationNumber = 0;
    qt.QTimer.singleShot(self.interval, self.updateStep)       
          
  def stopSteeredRegistration(self):
    slicer.mrmlScene.RemoveNode(self.axialFixedVolume)
    slicer.mrmlScene.RemoveNode(self.axialMovingVolume)

    self.actionState = "idle"
    self.removeObservers()

  def updateStep(self):
  
    self.registrationIterationNumber = self.registrationIterationNumber + 1
    #print('Registration iteration %d' %(self.registrationIterationNumber))
    
    #TODO: switch to while? clear queue immediately or do one at a time?
    if not self.actionQueue.empty():
      self.invoke_correction()

    self.polyAffine.optimize_step()

    # Only upsample and redraw updated image every N iterations
    if self.registrationIterationNumber % self.drawIterations == 0:
      self.outputImageCL = self.polyAffine.movingCL

      self.updateOutputVolume(self.outputImageCL)
      self.redrawSlices()

    # Initiate another iteration of the registration algorithm.
    if self.interaction:
      qt.QTimer.singleShot(self.interval, self.updateStep)

  def invoke_correction(self):
    
    """
    widget = slicer.modules.SteeredPolyAffineRegistrationWidget

    #fixedVolume = widget.fixedSelector.currentNode()
    #movingVolume = widget.movingSelector.currentNode()
    fixedVolume = self.axialFixedVolume
    movingVolume = self.axialMovingVolume

    imageSize = fixedVolume.GetImageData().GetDimensions()

    shape = self.fixedImageCL.shape
    spacing = self.fixedImageCL.spacing

    origin = movingVolume.GetOrigin()
    """

    spacing = self.fixedImageCL.spacing

    movingRAStoIJK = vtk.vtkMatrix4x4()
    self.axialMovingVolume.GetRASToIJKMatrix(movingRAStoIJK)

    actionItem = self.actionQueue.get()

    #TODO: draw green circle representing current input on images?

    startRAS = actionItem[5]
    endRAS = actionItem[6]

    startIJK = movingRAStoIJK.MultiplyPoint(startRAS + (1,))
    endIJK = movingRAStoIJK.MultiplyPoint(endRAS + (1,))

    x = np.zeros((3,), np.float32)
    y = np.zeros((3,), np.float32)

    maxd = 2.0
    for d in range(3):
      x[d] = startIJK[d] * spacing[d]
      y[d] = endIJK[d] * spacing[d]

      maxd = max(maxd, 1.05*abs(x[d]-y[d]))

    #r = np.ones((3,), np.float32) * maxd
    r = np.ones((3,), np.float32) * max(2.0, 1.05 * np.linalg.norm(x - y))

    steerMode = actionItem[1]

    if steerMode == "erase":
      # TODO: list of added affines, user can select to undo specific ones
      self.polyAffine.remove_affine(x, r[0])
      self.polyAffine.optimize_setup()
      return

    if steerMode == "rotate":
      steerer = SteeringRotation(self.fixedImageCL, self.movingImageCL, x, r)
    elif steerMode == "scale":
      steerer = SteeringScale(self.fixedImageCL, self.movingImageCL, x, r)
    else:
      print "WARNING: unknown steering action"
      return

    A, T = steerer.steer()

    # Append user defined affine to polyaffine
    self.polyAffine.add_affine(A, T, x, r)

    print "Added A", A, "T", T

    # TODO: reinitialize optimizer? Fix user affine?
    self.polyAffine.optimize_setup()

  def processEvent(self,observee,event=None):

    eventProcessed = False
  
    from slicer import app

    layoutManager = slicer.app.layoutManager()

    if self.sliceWidgetsPerStyle.has_key(observee):

      eventProcessed = True

      sliceWidget = self.sliceWidgetsPerStyle[observee]
      style = sliceWidget.sliceView().interactorStyle()
      self.interactor = style.GetInteractor()
      nodeIndex = self.nodeIndexPerStyle[observee]
      sliceNode = self.sliceNodePerStyle[observee]

      windowSize = sliceNode.GetDimensions()
      windowW = float(windowSize[0])
      windowH = float(windowSize[1])

      aspectRatio = windowH/windowW

      self.lastDrawnSliceWidget = sliceWidget
  
      if event == "EnterEvent":
        # TODO check interaction mode (eg tugging vs squishing)
        cursor = qt.QCursor(qt.Qt.OpenHandCursor)
        app.setOverrideCursor(cursor)
        
        self.actionState = "interacting"
        
        self.abortEvent(event)

      elif event == "LeaveEvent":
        
        cursor = qt.QCursor(qt.Qt.ArrowCursor)
        app.setOverrideCursor(cursor)
        #app.restoreOverrideCursor()
        
        self.actionState = "idle"
        
        self.abortEvent(event)
      
      elif event == "LeftButtonPressEvent":

        if nodeIndex > 2:

          cursor = qt.QCursor(qt.Qt.ClosedHandCursor)
          app.setOverrideCursor(cursor)
        
          xy = style.GetInteractor().GetEventPosition()
          xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy)
          ras = sliceWidget.sliceView().convertXYZToRAS(xyz)

          self.startEventPosition = ras
        
          self.actionState = "steerStart"

          self.steerStartTime = time.clock()
        
          self.steerStartXY = xy
          self.steerStartRAS = ras
      
        else:
          self.actionState = "clickReject"

        self.abortEvent(event)

      elif event == "LeftButtonReleaseEvent":
      
        if self.actionState == "steerStart":
          cursor = qt.QCursor(qt.Qt.OpenHandCursor)
          app.setOverrideCursor(cursor)

          xy = style.GetInteractor().GetEventPosition()
          xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy)
          ras = sliceWidget.sliceView().convertXYZToRAS(xyz)

          self.lastEventPosition = ras

          self.steerEndXY = xy
          self.steerEndRAS = ras

          # TODO: only draw line within ??? seconds
          self.lastDrawMTime = sliceNode.GetMTime()
          
          self.lastDrawSliceWidget = sliceWidget

          self.actionQueue.put(
            (sliceNode.GetMTime(), self.steerMode, sliceWidget,
             self.steerStartXY, self.steerEndXY,
             self.steerStartRAS, self.steerEndRAS) )

          renOverlay = self.getOverlayRenderer(
            style.GetInteractor().GetRenderWindow() )
          renOverlay.RemoveActor(self.roiActor)

        self.actionState = "interacting"
        
        self.abortEvent(event)

      elif event == "MouseMoveEvent":

        if self.actionState == "interacting":

          """
          xy = style.GetInteractor().GetEventPosition()
          xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy)
          ras = sliceWidget.sliceView().convertXYZToRAS(xyz)
          
          w = slicer.modules.SteeredPolyAffineRegistrationWidget
          
          movingRAStoIJK = vtk.vtkMatrix4x4()
          w.movingSelector.currentNode().GetRASToIJKMatrix(movingRAStoIJK)
     
          ijk = movingRAStoIJK.MultiplyPoint(ras + (1,))
          """
          
          if nodeIndex > 2:
            cursor = qt.QCursor(qt.Qt.OpenHandCursor)
            app.setOverrideCursor(cursor)
          else:
            cursor = qt.QCursor(qt.Qt.ForbiddenCursor)
            app.setOverrideCursor(cursor)
            
        elif self.actionState == "steerStart":

          # Drawing a line that shows ROI
          cursor = qt.QCursor(qt.Qt.ClosedHandCursor)
          app.setOverrideCursor(cursor)

          xy = style.GetInteractor().GetEventPosition()

          self.drawROI(style.GetInteractor(), self.steerStartXY, xy)

          # TODO: draw ROI on the fixed image as well?
          """
          otherSliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex-3, 'vtkMRMLSliceNode')
          otherSliceWidget = layoutManager.sliceWidget(otherSliceNode.GetLayoutName())
          otherSliceView = otherSliceWidget.sliceView()
          otherSliceStyle = otherSliceWidget.interactorStyle()

          # TODO: reuse actor?
          #self.drawROI(otherSliceStyle.GetInteractor(), self.steerStartXY, xy)
          otherSliceStyle.GetInteractor().
          renOverlay = self.getOverlayRenderer(
            otherSliceStyle.GetInteractor().GetRenderWindow() )
          renOverlay.AddActor(self.roiActor)
          """

        else:
          pass
        
        
        self.abortEvent(event)
          
      else:
        eventProcessed = False

    if eventProcessed:
      self.redrawSlices()

  def removeObservers(self):
    # remove observers and reset
    for tag in self.interactorObserverTags:
      self.interactor.RemoveObserver(tag)
    self.interactorObserverTags = []
    self.sliceWidgetsPerStyle = {}
    

  def abortEvent(self,event):
    """Set the AbortFlag on the vtkCommand associated
    with the event - causes other things listening to the
    interactor not to receive the events"""
    # TODO: make interactorObserverTags a map to we can
    # explicitly abort just the event we handled - it will
    # be slightly more efficient
    for tag in self.interactorObserverTags:
      cmd = self.interactor.GetCommand(tag)
      if cmd is not None:
        cmd.SetAbortFlag(1)

  def drawROI(self, interactor, startXY, endXY):
    coord = vtk.vtkCoordinate()
    coord.SetCoordinateSystemToDisplay()

    coord.SetValue(startXY[0], startXY[1], 0.0)
    worldStartXY = coord.GetComputedWorldValue(interactor.GetRenderWindow().GetRenderers().GetFirstRenderer())

    coord.SetValue(endXY[0], endXY[1], 0.0)
    worldEndXY = coord.GetComputedWorldValue(interactor.GetRenderWindow().GetRenderers().GetFirstRenderer())

    pts = vtk.vtkPoints()
    pts.InsertNextPoint(worldStartXY)

    vectors = vtk.vtkDoubleArray()
    vectors.SetNumberOfComponents(3)
    vectors.SetNumberOfTuples(1)
    vectors.SetTuple3(0, worldEndXY[0]-worldStartXY[0], worldEndXY[1]-worldStartXY[1], worldEndXY[2]-worldStartXY[2]) 

    r = 0
    for d in range(3):
      r += (worldEndXY[d] - worldStartXY[d]) ** 2.0
    r = math.sqrt(r)

    radii = vtk.vtkFloatArray()
    radii.InsertNextValue(r)
    radii.SetName("radius")

    pd = vtk.vtkPolyData()
    pd.SetPoints(pts)
    #pd.GetPointData().SetVectors(vectors)
    #pd.GetPointData().AddArray(radii)
    #pd.GetPointData().SetActiveScalars("radius")
    pd.GetPointData().SetScalars(radii)

    #lineSource = vtk.vtkArrowSource()

    """
    lineSource = vtk.vtkGlyphSource2D()
    lineSource.SetGlyphTypeToCircle()
    #lineSource.SetGlyphTypeToArrow()
    lineSource.FilledOff()
    lineSource.Update()
    """

    lineSource = vtk.vtkSphereSource()
    lineSource.SetRadius(1.0)
    lineSource.SetPhiResolution(12)
    lineSource.SetThetaResolution(12)

    self.roiGlyph.SetInput(pd)
    self.roiGlyph.SetSource(lineSource.GetOutput())
    self.roiGlyph.ScalingOn()
    self.roiGlyph.OrientOn()
    self.roiGlyph.SetScaleFactor(1.0)
    #self.roiGlyph.SetVectorModeToUseVector()
    #self.roiGlyph.SetScaleModeToScaleByVector()
    self.roiGlyph.SetScaleModeToScaleByScalar()
    self.roiGlyph.Update()
     
    self.roiMapper.SetInput(self.roiGlyph.GetOutput())

    self.roiActor.SetMapper(self.roiMapper)

    renOverlay = self.getOverlayRenderer( interactor.GetRenderWindow() )
    renOverlay.AddActor(self.roiActor)

  def redrawSlices(self):
    # TODO: memory leak

    layoutManager = slicer.app.layoutManager()
    sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode')
    for nodeIndex in xrange(sliceNodeCount):
      # find the widget for each node in scene
      sliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex, 'vtkMRMLSliceNode')
      sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName())
      
      if sliceWidget:
        renwin = sliceWidget.sliceView().renderWindow()
        rencol = renwin.GetRenderers()
        if rencol.GetNumberOfItems() >= 2:
          rencol.GetItemAsObject(1).RemoveActor(self.linesActor)
          
        renwin.Render()
        
  def getOverlayRenderer(self, renwin):
    rencol = renwin.GetRenderers()
      
    renOverlay = None
    if rencol.GetNumberOfItems() >= 2:
      renOverlay = rencol.GetItemAsObject(1)
    else:
      renOverlay = vtk.vtkRenderer()
      renwin.SetNumberOfLayers(2)
      renwin.AddRenderer(renOverlay)

    #renOverlay.SetInteractive(0)
    #renOverlay.SetLayer(1)

    return renOverlay

  def testingData(self):
    """Load some default data for development
    and set up a transform and viewing scenario for it.
    """

    #import SampleData
    #sampleDataLogic = SampleData.SampleDataLogic()
    #mrHead = sampleDataLogic.downloadMRHead()
    #dtiBrain = sampleDataLogic.downloadDTIBrain()
    
    # w = slicer.modules.SteeredPolyAffineRegistrationWidget
    # w.fixedSelector.setCurrentNode(mrHead)
    # w.movingSelector.setCurrentNode(dtiBrain)

    sourcePath = os.path.dirname(slicer.modules.steeredpolyaffineregistration.path)
    
    if not slicer.util.getNodes('blob_big*'):
      fileName = os.path.join(sourcePath, "Testing", "blob_big.mha")
      vl = slicer.modules.volumes.logic()
      brain1Node = vl.AddArchetypeVolume(fileName, "blob_big", 0)
    else:
      nodes = slicer.util.getNodes('blob_big.mha')
      brain1Node = nodes[0]

    if not slicer.util.getNodes('blob_small*'):
      fileName = os.path.join(sourcePath, "Testing", "blob_small.mha")
      vl = slicer.modules.volumes.logic()
      brain2Node = vl.AddArchetypeVolume(fileName, "blob_small", 0)
    #TODO else assign from list

    # if not slicer.util.getNodes('movingToFixed*'):
      # # Create transform node
      # transform = slicer.vtkMRMLLinearTransformNode()
      # transform.SetName('movingToFixed')
      # slicer.mrmlScene.AddNode(transform)

    # transform = slicer.util.getNode('movingToFixed')
    
    # ###
    # # neutral.SetAndObserveTransformNodeID(transform.GetID())
    # ###
    
    compositeNodes = slicer.util.getNodes('vtkMRMLSliceCompositeNode*')
    for compositeNode in compositeNodes.values():
      compositeNode.SetBackgroundVolumeID(brain1Node.GetID())
      compositeNode.SetForegroundVolumeID(brain2Node.GetID())
      compositeNode.SetForegroundOpacity(0.5)
    applicationLogic = slicer.app.applicationLogic()
    applicationLogic.FitSliceToAll()