Example #1
0
 def __init__( self, stepid ):
   self.initialize( stepid )
   self.setName( '5. Place Screws' )
   self.setDescription( 'Load screw models and change orientation using sliders' )
   self.screwPath = None
   self.screwName = None
   self.coords = [0,0,0]
   self.matrix1 = vtk.vtkMatrix3x3()
   self.matrix2 = vtk.vtkMatrix3x3()
   self.matrix3 = vtk.vtkMatrix3x3()
   self.matrixScrew = vtk.vtkMatrix4x4()
   self.fiduciallist = []
   self.screwSummary = []
   
   self.screwList = []
   self.currentFidIndex = 0
   self.currentFidLabel = None
             
   self.fidNode = slicer.vtkMRMLMarkupsFiducialNode()
   
   self.valueTemp1 = 0
   self.valueTemp2 = 0
   self.driveTemp = 0
   
   self.__loadScrewButton = None
   self.__parent = super( ScrewStep, self )
   
   self.timer = qt.QTimer()
   self.timer.setInterval(2)
   self.timer.connect('timeout()', self.driveScrew)
   self.timer2 = qt.QTimer()
   self.timer2.setInterval(2)
   self.timer2.connect('timeout()', self.reverseScrew)
   self.screwInsert = 0.0
    def transformScrewComposite(self, inputMatrix):

        transformFid = slicer.mrmlScene.GetFirstNodeByName(
            'Transform-%s' % self.currentFidLabel)

        matrixScrew = transformFid.GetMatrixTransformToParent()

        newMatrix = vtk.vtkMatrix3x3()
        outputMatrix = vtk.vtkMatrix3x3()

        newMatrix.SetElement(0, 0, matrixScrew.GetElement(0, 0))
        newMatrix.SetElement(0, 1, matrixScrew.GetElement(0, 1))
        newMatrix.SetElement(0, 2, matrixScrew.GetElement(0, 2))

        newMatrix.SetElement(1, 0, matrixScrew.GetElement(1, 0))
        newMatrix.SetElement(1, 1, matrixScrew.GetElement(1, 1))
        newMatrix.SetElement(1, 2, matrixScrew.GetElement(1, 2))

        newMatrix.SetElement(2, 0, matrixScrew.GetElement(2, 0))
        newMatrix.SetElement(2, 1, matrixScrew.GetElement(2, 1))
        newMatrix.SetElement(2, 2, matrixScrew.GetElement(2, 2))

        vtk.vtkMatrix3x3.Multiply3x3(newMatrix, inputMatrix, outputMatrix)

        #coords = [0,0,0]
        #self.fid.GetFiducialCoordinates(coords)

        matrixScrew.SetElement(0, 0, outputMatrix.GetElement(0, 0))
        matrixScrew.SetElement(0, 1, outputMatrix.GetElement(0, 1))
        matrixScrew.SetElement(0, 2, outputMatrix.GetElement(0, 2))
        #matrixScrew.SetElement(0,3,self.coords[0])

        matrixScrew.SetElement(1, 0, outputMatrix.GetElement(1, 0))
        matrixScrew.SetElement(1, 1, outputMatrix.GetElement(1, 1))
        matrixScrew.SetElement(1, 2, outputMatrix.GetElement(1, 2))
        #matrixScrew.SetElement(1,3,self.coords[1])

        matrixScrew.SetElement(2, 0, outputMatrix.GetElement(2, 0))
        matrixScrew.SetElement(2, 1, outputMatrix.GetElement(2, 1))
        matrixScrew.SetElement(2, 2, outputMatrix.GetElement(2, 2))
        #matrixScrew.SetElement(2,3,self.coords[2])

        matrixScrew.SetElement(3, 0, 0)
        matrixScrew.SetElement(3, 1, 0)
        matrixScrew.SetElement(3, 2, 0)
        matrixScrew.SetElement(3, 3, 1)

        transformFid.SetMatrixTransformToParent(matrixScrew)

        transformFid.UpdateScene(slicer.mrmlScene)
    def transformScrewComposite(self, inputMatrix):

        transformFid = slicer.util.getNode('Transform-%s' % self.currentFidLabel)
        
        matrixScrew = transformFid.GetMatrixTransformToParent()
        
        newMatrix = vtk.vtkMatrix3x3()
        outputMatrix = vtk.vtkMatrix3x3()
        
        newMatrix.SetElement(0,0,matrixScrew.GetElement(0,0))
        newMatrix.SetElement(0,1,matrixScrew.GetElement(0,1))
        newMatrix.SetElement(0,2,matrixScrew.GetElement(0,2))
        
        newMatrix.SetElement(1,0,matrixScrew.GetElement(1,0))
        newMatrix.SetElement(1,1,matrixScrew.GetElement(1,1))
        newMatrix.SetElement(1,2,matrixScrew.GetElement(1,2))
        
        newMatrix.SetElement(2,0,matrixScrew.GetElement(2,0))
        newMatrix.SetElement(2,1,matrixScrew.GetElement(2,1))
        newMatrix.SetElement(2,2,matrixScrew.GetElement(2,2))
        
        vtk.vtkMatrix3x3.Multiply3x3(newMatrix, inputMatrix, outputMatrix)
        
        #coords = [0,0,0]  
        #self.fid.GetFiducialCoordinates(coords)
        
        matrixScrew.SetElement(0,0,outputMatrix.GetElement(0,0))
        matrixScrew.SetElement(0,1,outputMatrix.GetElement(0,1))
        matrixScrew.SetElement(0,2,outputMatrix.GetElement(0,2))
        #matrixScrew.SetElement(0,3,self.coords[0])
        
        matrixScrew.SetElement(1,0,outputMatrix.GetElement(1,0))
        matrixScrew.SetElement(1,1,outputMatrix.GetElement(1,1))
        matrixScrew.SetElement(1,2,outputMatrix.GetElement(1,2))
        #matrixScrew.SetElement(1,3,self.coords[1])
        
        matrixScrew.SetElement(2,0,outputMatrix.GetElement(2,0))
        matrixScrew.SetElement(2,1,outputMatrix.GetElement(2,1))
        matrixScrew.SetElement(2,2,outputMatrix.GetElement(2,2))
        #matrixScrew.SetElement(2,3,self.coords[2])
        
        matrixScrew.SetElement(3,0,0)
        matrixScrew.SetElement(3,1,0)
        matrixScrew.SetElement(3,2,0)
        matrixScrew.SetElement(3,3,1)

        transformFid.SetMatrixTransformToParent(matrixScrew)

        transformFid.UpdateScene(slicer.mrmlScene)
Example #4
0
    def getVTKMatrixFromNumpyMatrix(self, numpyMatrix):
        dimensions = len(numpyMatrix) - 1
        if dimensions == 2:
            vtkMatrix = vtk.vtkMatrix3x3()
        elif dimensions == 3:
            vtkMatrix = vtk.vtkMatrix4x4()
        else:
            raise ValueError('Unknown matrix dimensions.')

        for row in range(dimensions + 1):
            for col in range(dimensions + 1):
                vtkMatrix.SetElement(row, col, numpyMatrix[row, col])
        return vtkMatrix
    def driveScrew(self):
        if self.screwInsert < int(self.__diameter):

            value = self.screwInsert
            # attempt to rotate with driving

            angle3 = math.pi / 180.0 * 72  #((360/2.5)*self.screwInsert)

            matrix3 = vtk.vtkMatrix3x3()
            matrix3.DeepCopy([
                math.cos(angle3), 0, -math.sin(angle3), 0, 1, 0,
                math.sin(angle3), 0,
                math.cos(angle3)
            ])

            self.transformScrewComposite(matrix3)

            value = value * -1
            transformFid = slicer.mrmlScene.GetFirstNodeByName(
                'Transform-%s' % self.currentFidLabel)

            matrixScrew = transformFid.GetMatrixTransformToParent()

            newVal = value - self.driveTemp

            drive1 = matrixScrew.GetElement(0, 1)
            drive2 = matrixScrew.GetElement(1, 1)
            drive3 = matrixScrew.GetElement(2, 1)

            coord1 = drive1 * newVal + matrixScrew.GetElement(0, 3)
            coord2 = drive2 * newVal + matrixScrew.GetElement(1, 3)
            coord3 = drive3 * newVal + matrixScrew.GetElement(2, 3)

            matrixScrew.SetElement(0, 3, coord1)
            matrixScrew.SetElement(1, 3, coord2)
            matrixScrew.SetElement(2, 3, coord3)

            transformFid.SetMatrixTransformToParent(matrixScrew)

            #transformFid.UpdateScene(slicer.mrmlScene)
            #self.delayDisplay(transformFid.UpdateScene(slicer.mrmlScene), 2000)
            self.driveTemp = value
            self.screwInsert += 1
        else:
            self.timer.stop()
            self.screwInsert = 0.0
            self.driveTemp = 0
        '''    
    def driveScrew(self):
        if self.screwInsert < int(self.__diameter):
            
            value = self.screwInsert
            #print(value)
            # attempt to rotate with driving        
            
            angle3 = math.pi / 180.0 * 72 #((360/2.5)*self.screwInsert) 
        
            matrix3 = vtk.vtkMatrix3x3()
            matrix3.DeepCopy([ math.cos(angle3), 0, -math.sin(angle3),
                          0, 1, 0,
                          math.sin(angle3), 0, math.cos(angle3)])
        
            self.transformScrewComposite(matrix3)


            value = value*-1
            transformFid = slicer.util.getNode('Transform-%s' % self.currentFidLabel)
        
            matrixScrew = transformFid.GetMatrixTransformToParent()
        
            newVal = value - self.driveTemp
            print(newVal)
        
            drive1 = matrixScrew.GetElement(0,1)
            drive2 = matrixScrew.GetElement(1,1)
            drive3 = matrixScrew.GetElement(2,1)
        
            coord1 = drive1 * newVal + matrixScrew.GetElement(0,3)
            coord2 = drive2 * newVal + matrixScrew.GetElement(1,3)
            coord3 = drive3 * newVal + matrixScrew.GetElement(2,3)
        
            matrixScrew.SetElement(0,3,coord1)
            matrixScrew.SetElement(1,3,coord2)
            matrixScrew.SetElement(2,3,coord3)

            transformFid.SetMatrixTransformToParent(matrixScrew)
                
            #transformFid.UpdateScene(slicer.mrmlScene)
            #self.delayDisplay(transformFid.UpdateScene(slicer.mrmlScene), 2000)
            self.driveTemp = value
            self.screwInsert += 1
        else:
            self.timer.stop()  
            self.screwInsert = 0.0 
            self.driveTemp = 0  
        '''    
Example #7
0
 def transformSlider2ValueChanged(self, value):
     print(value)
     
     newValue = value - self.valueTemp2
     
     angle2 = math.pi / 180.0 * newValue * -1 # Match screw direction
     
     matrix2 = vtk.vtkMatrix3x3()
     matrix2.DeepCopy([ math.cos(angle2), -math.sin(angle2), 0,
                       math.sin(angle2), math.cos(angle2), 0,
                       0, 0, 1])
     
     self.transformScrewComposite(matrix2)
     
     self.valueTemp2 = value
     
     temp = self.screwList[self.currentFidIndex]
     temp[5] = str(value)
     self.screwList[self.currentFidIndex] = temp
     print self.screwList
    def transformSlider2ValueChanged(self, value):
        logging.debug("Transform slider 2 changed: {0}".format(value))

        newValue = value - self.valueTemp2

        angle2 = math.pi / 180.0 * newValue * -1 # Match screw direction

        matrix2 = vtk.vtkMatrix3x3()
        matrix2.DeepCopy([ math.cos(angle2), -math.sin(angle2), 0,
                          math.sin(angle2), math.cos(angle2), 0,
                          0, 0, 1])

        self.transformScrewComposite(matrix2)

        self.valueTemp2 = value

        temp = self.screwList[self.currentFidIndex]
        temp[5] = str(value)
        self.screwList[self.currentFidIndex] = temp
        logging.debug("Screw list: {0}".format(self.screwList))
Example #9
0
  def sampleVolumeParameters(self):
    """Calculate the dictionary of substitutions for the
    current state of the volume node in a form for
    substitution into the sampleVolume shader function
    TODO: this would probably be better as uniforms, but that
    requires doing a lot of parsing and data management in C++
    """

    rasToIJK = vtk.vtkMatrix4x4()
    self.node.GetRASToIJKMatrix(rasToIJK)

    transformNode = self.node.GetParentTransformNode()
    if transformNode:
      if transformNode.IsTransformToWorldLinear():
        rasToRAS = vtk.vtkMatrix4x4()
        transformNode.GetMatrixTransformToWorld(rasToRAS)
        rasToRAS.Invert()
        rasToRAS.Multiply4x4(rasToIJK, rasToRAS, rasToIJK)
      else:
        error.warn('Cannot handle nonlinear transforms')

    # dimensions are number of pixels in (row, column, slice)
    # which maps to 0-1 space of S, T, P
    dimensions = self.node.GetImageData().GetDimensions()
    ijkToSTP = vtk.vtkMatrix4x4()
    ijkToSTP.Identity()
    for diagonal in range(3):
      ijkToSTP.SetElement(diagonal,diagonal, 1./dimensions[diagonal])
    rasToSTP = vtk.vtkMatrix4x4()
    ijkToSTP.Multiply4x4(ijkToSTP, rasToIJK, rasToSTP)

    parameters = {}
    rows = ('rasToS', 'rasToT', 'rasToP')
    for row in range(3):
      rowKey = rows[row]
      parameters[rowKey] = ""
      for col in range(4):
        element = rasToSTP.GetElement(row,col)
        parameters[rowKey] += "%f," % element
      parameters[rowKey] = parameters[rowKey][:-1] # clear trailing comma

    # since texture is 0-1, take into account both pixel spacing
    # and dimension as layed out in memory so that the normals
    # is calculated in a uniform space
    spacings = self.node.GetSpacing()
    parameters['mmToS'] = spacings[0] / dimensions[0]
    parameters['mmToT'] = spacings[1] / dimensions[1]
    parameters['mmToP'] = spacings[2] / dimensions[2]

    # the inverse transpose of the upper 3x3 of the stpToRAS matrix,
    # which is the transpose of the upper 3x3 of the rasTSTP matrix
    normalSTPToRAS = vtk.vtkMatrix3x3();
    for row in range(3):
      for column in range(3):
        normalSTPToRAS.SetElement(row,column, rasToSTP.GetElement(row,column));
    normalSTPToRAS.Transpose()
    parameters['normalSTPToRAS'] = ''
    for column in range(3):
      for row in range(3):
        # write in column-major order for glsl mat3 constructor
        parameters['normalSTPToRAS'] += "%f," % normalSTPToRAS.GetElement(row,column)
    parameters['normalSTPToRAS'] = parameters['normalSTPToRAS'][:-1] # clear trailing comma

    return parameters
Example #10
0
  def getPlaneIntersectionPoint(self, axialNode, ortho1Node, ortho2Node):
    # Compute the center of rotation (common intersection point of the three planes)
    # http://mathworld.wolfram.com/Plane-PlaneIntersection.html
        
    #axialNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')
    #ortho1Node = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')
    #ortho2Node = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeGreen')

    axialSliceToRas = axialNode.GetSliceToRAS()
    n1 = [axialSliceToRas.GetElement(0,2),axialSliceToRas.GetElement(1,2),axialSliceToRas.GetElement(2,2)]
    x1 = [axialSliceToRas.GetElement(0,3),axialSliceToRas.GetElement(1,3),axialSliceToRas.GetElement(2,3)]

    ortho1SliceToRas = ortho1Node.GetSliceToRAS()
    n2 = [ortho1SliceToRas.GetElement(0,2),ortho1SliceToRas.GetElement(1,2),ortho1SliceToRas.GetElement(2,2)]
    x2 = [ortho1SliceToRas.GetElement(0,3),ortho1SliceToRas.GetElement(1,3),ortho1SliceToRas.GetElement(2,3)]

    ortho2SliceToRas = ortho2Node.GetSliceToRAS()
    n3 = [ortho2SliceToRas.GetElement(0,2),ortho2SliceToRas.GetElement(1,2),ortho2SliceToRas.GetElement(2,2)]
    x3 = [ortho2SliceToRas.GetElement(0,3),ortho2SliceToRas.GetElement(1,3),ortho2SliceToRas.GetElement(2,3)]

    # Computed intersection point of all planes
    x = [0,0,0]    

    n2_xp_n3 = [0,0,0]
    x1_dp_n1 = vtk.vtkMath.Dot(x1,n1)
    vtk.vtkMath.Cross(n2,n3,n2_xp_n3)
    vtk.vtkMath.MultiplyScalar(n2_xp_n3, x1_dp_n1)
    vtk.vtkMath.Add(x,n2_xp_n3,x)

    n3_xp_n1 = [0,0,0]
    x2_dp_n2 = vtk.vtkMath.Dot(x2,n2)
    vtk.vtkMath.Cross(n3,n1,n3_xp_n1)
    vtk.vtkMath.MultiplyScalar(n3_xp_n1, x2_dp_n2)
    vtk.vtkMath.Add(x,n3_xp_n1,x)

    n1_xp_n2 = [0,0,0]
    x3_dp_n3 = vtk.vtkMath.Dot(x3,n3)
    vtk.vtkMath.Cross(n1,n2,n1_xp_n2)
    vtk.vtkMath.MultiplyScalar(n1_xp_n2, x3_dp_n3)
    vtk.vtkMath.Add(x,n1_xp_n2,x)

    normalMatrix = vtk.vtkMatrix3x3()
    normalMatrix.SetElement(0,0,n1[0])
    normalMatrix.SetElement(1,0,n1[1])
    normalMatrix.SetElement(2,0,n1[2])
    normalMatrix.SetElement(0,1,n2[0])
    normalMatrix.SetElement(1,1,n2[1])
    normalMatrix.SetElement(2,1,n2[2])
    normalMatrix.SetElement(0,2,n3[0])
    normalMatrix.SetElement(1,2,n3[1])
    normalMatrix.SetElement(2,2,n3[2])
    normalMatrixDeterminant = normalMatrix.Determinant()
    
    if abs(normalMatrixDeterminant)>0.01:
      # there is an intersection point
      vtk.vtkMath.MultiplyScalar(x, 1/normalMatrixDeterminant)
    else:
      # no intersection point can be determined, use just the position of the axial slice
      x = x1
    
    return x
Example #11
0
def getPlaneIntersectionPoint(axialNode, ortho1Node, ortho2Node):
    """
  Compute the center of rotation (common intersection point of the three planes)
  http://mathworld.wolfram.com/Plane-PlaneIntersection.html
  Copied from ValveViewLogic to remove dependency on SlicerHeart extension.
  """

    axialSliceToRas = axialNode.GetSliceToRAS()
    n1 = [
        axialSliceToRas.GetElement(0, 2),
        axialSliceToRas.GetElement(1, 2),
        axialSliceToRas.GetElement(2, 2)
    ]
    x1 = [
        axialSliceToRas.GetElement(0, 3),
        axialSliceToRas.GetElement(1, 3),
        axialSliceToRas.GetElement(2, 3)
    ]

    ortho1SliceToRas = ortho1Node.GetSliceToRAS()
    n2 = [
        ortho1SliceToRas.GetElement(0, 2),
        ortho1SliceToRas.GetElement(1, 2),
        ortho1SliceToRas.GetElement(2, 2)
    ]
    x2 = [
        ortho1SliceToRas.GetElement(0, 3),
        ortho1SliceToRas.GetElement(1, 3),
        ortho1SliceToRas.GetElement(2, 3)
    ]

    ortho2SliceToRas = ortho2Node.GetSliceToRAS()
    n3 = [
        ortho2SliceToRas.GetElement(0, 2),
        ortho2SliceToRas.GetElement(1, 2),
        ortho2SliceToRas.GetElement(2, 2)
    ]
    x3 = [
        ortho2SliceToRas.GetElement(0, 3),
        ortho2SliceToRas.GetElement(1, 3),
        ortho2SliceToRas.GetElement(2, 3)
    ]

    # Computed intersection point of all planes
    x = [0, 0, 0]

    n2_xp_n3 = [0, 0, 0]
    x1_dp_n1 = vtk.vtkMath.Dot(x1, n1)
    vtk.vtkMath.Cross(n2, n3, n2_xp_n3)
    vtk.vtkMath.MultiplyScalar(n2_xp_n3, x1_dp_n1)
    vtk.vtkMath.Add(x, n2_xp_n3, x)

    n3_xp_n1 = [0, 0, 0]
    x2_dp_n2 = vtk.vtkMath.Dot(x2, n2)
    vtk.vtkMath.Cross(n3, n1, n3_xp_n1)
    vtk.vtkMath.MultiplyScalar(n3_xp_n1, x2_dp_n2)
    vtk.vtkMath.Add(x, n3_xp_n1, x)

    n1_xp_n2 = [0, 0, 0]
    x3_dp_n3 = vtk.vtkMath.Dot(x3, n3)
    vtk.vtkMath.Cross(n1, n2, n1_xp_n2)
    vtk.vtkMath.MultiplyScalar(n1_xp_n2, x3_dp_n3)
    vtk.vtkMath.Add(x, n1_xp_n2, x)

    normalMatrix = vtk.vtkMatrix3x3()
    normalMatrix.SetElement(0, 0, n1[0])
    normalMatrix.SetElement(1, 0, n1[1])
    normalMatrix.SetElement(2, 0, n1[2])
    normalMatrix.SetElement(0, 1, n2[0])
    normalMatrix.SetElement(1, 1, n2[1])
    normalMatrix.SetElement(2, 1, n2[2])
    normalMatrix.SetElement(0, 2, n3[0])
    normalMatrix.SetElement(1, 2, n3[1])
    normalMatrix.SetElement(2, 2, n3[2])
    normalMatrixDeterminant = normalMatrix.Determinant()

    if abs(normalMatrixDeterminant) > 0.01:
        # there is an intersection point
        vtk.vtkMath.MultiplyScalar(x, 1 / normalMatrixDeterminant)
    else:
        # no intersection point can be determined, use just the position of the axial slice
        x = x1

    return x
Example #12
0
    def getPlaneIntersectionPoint(self, axialNode, ortho1Node, ortho2Node):
        # Compute the center of rotation (common intersection point of the three planes)
        # http://mathworld.wolfram.com/Plane-PlaneIntersection.html

        #axialNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')
        #ortho1Node = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')
        #ortho2Node = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeGreen')

        axialSliceToRas = axialNode.GetSliceToRAS()
        n1 = [
            axialSliceToRas.GetElement(0, 2),
            axialSliceToRas.GetElement(1, 2),
            axialSliceToRas.GetElement(2, 2)
        ]
        x1 = [
            axialSliceToRas.GetElement(0, 3),
            axialSliceToRas.GetElement(1, 3),
            axialSliceToRas.GetElement(2, 3)
        ]

        ortho1SliceToRas = ortho1Node.GetSliceToRAS()
        n2 = [
            ortho1SliceToRas.GetElement(0, 2),
            ortho1SliceToRas.GetElement(1, 2),
            ortho1SliceToRas.GetElement(2, 2)
        ]
        x2 = [
            ortho1SliceToRas.GetElement(0, 3),
            ortho1SliceToRas.GetElement(1, 3),
            ortho1SliceToRas.GetElement(2, 3)
        ]

        ortho2SliceToRas = ortho2Node.GetSliceToRAS()
        n3 = [
            ortho2SliceToRas.GetElement(0, 2),
            ortho2SliceToRas.GetElement(1, 2),
            ortho2SliceToRas.GetElement(2, 2)
        ]
        x3 = [
            ortho2SliceToRas.GetElement(0, 3),
            ortho2SliceToRas.GetElement(1, 3),
            ortho2SliceToRas.GetElement(2, 3)
        ]

        # Computed intersection point of all planes
        x = [0, 0, 0]

        n2_xp_n3 = [0, 0, 0]
        x1_dp_n1 = vtk.vtkMath.Dot(x1, n1)
        vtk.vtkMath.Cross(n2, n3, n2_xp_n3)
        vtk.vtkMath.MultiplyScalar(n2_xp_n3, x1_dp_n1)
        vtk.vtkMath.Add(x, n2_xp_n3, x)

        n3_xp_n1 = [0, 0, 0]
        x2_dp_n2 = vtk.vtkMath.Dot(x2, n2)
        vtk.vtkMath.Cross(n3, n1, n3_xp_n1)
        vtk.vtkMath.MultiplyScalar(n3_xp_n1, x2_dp_n2)
        vtk.vtkMath.Add(x, n3_xp_n1, x)

        n1_xp_n2 = [0, 0, 0]
        x3_dp_n3 = vtk.vtkMath.Dot(x3, n3)
        vtk.vtkMath.Cross(n1, n2, n1_xp_n2)
        vtk.vtkMath.MultiplyScalar(n1_xp_n2, x3_dp_n3)
        vtk.vtkMath.Add(x, n1_xp_n2, x)

        normalMatrix = vtk.vtkMatrix3x3()
        normalMatrix.SetElement(0, 0, n1[0])
        normalMatrix.SetElement(1, 0, n1[1])
        normalMatrix.SetElement(2, 0, n1[2])
        normalMatrix.SetElement(0, 1, n2[0])
        normalMatrix.SetElement(1, 1, n2[1])
        normalMatrix.SetElement(2, 1, n2[2])
        normalMatrix.SetElement(0, 2, n3[0])
        normalMatrix.SetElement(1, 2, n3[1])
        normalMatrix.SetElement(2, 2, n3[2])
        normalMatrixDeterminant = normalMatrix.Determinant()

        if abs(normalMatrixDeterminant) > 0.01:
            # there is an intersection point
            vtk.vtkMath.MultiplyScalar(x, 1 / normalMatrixDeterminant)
        else:
            # no intersection point can be determined, use just the position of the axial slice
            x = x1

        return x
Example #13
0
    def sampleVolumeParameters(self):
        """Calculate the dictionary of substitutions for the
    current state of the volume node in a form for
    substitution into the sampleVolume shader function
    TODO: this would probably be better as uniforms, but that
    requires doing a lot of parsing and data management in C++
    """

        rasToIJK = vtk.vtkMatrix4x4()
        self.node.GetRASToIJKMatrix(rasToIJK)

        transformNode = self.node.GetParentTransformNode()
        if transformNode:
            if transformNode.IsTransformToWorldLinear():
                rasToRAS = vtk.vtkMatrix4x4()
                transformNode.GetMatrixTransformToWorld(rasToRAS)
                rasToRAS.Invert()
                rasToRAS.Multiply4x4(rasToIJK, rasToRAS, rasToIJK)
            else:
                error.warn('Cannot handle nonlinear transforms')

        # dimensions are number of pixels in (row, column, slice)
        # which maps to 0-1 space of S, T, P
        dimensions = self.node.GetImageData().GetDimensions()
        ijkToSTP = vtk.vtkMatrix4x4()
        ijkToSTP.Identity()
        for diagonal in range(3):
            ijkToSTP.SetElement(diagonal, diagonal, 1. / dimensions[diagonal])
        rasToSTP = vtk.vtkMatrix4x4()
        ijkToSTP.Multiply4x4(ijkToSTP, rasToIJK, rasToSTP)

        parameters = {}
        rows = ('rasToS', 'rasToT', 'rasToP')
        for row in range(3):
            rowKey = rows[row]
            parameters[rowKey] = ""
            for col in range(4):
                element = rasToSTP.GetElement(row, col)
                parameters[rowKey] += "%f," % element
            parameters[rowKey] = parameters[rowKey][:
                                                    -1]  # clear trailing comma

        # since texture is 0-1, take into account both pixel spacing
        # and dimension as layed out in memory so that the normals
        # is calculated in a uniform space
        spacings = self.node.GetSpacing()
        parameters['mmToS'] = spacings[0] / dimensions[0]
        parameters['mmToT'] = spacings[1] / dimensions[1]
        parameters['mmToP'] = spacings[2] / dimensions[2]

        # the inverse transpose of the upper 3x3 of the stpToRAS matrix,
        # which is the transpose of the upper 3x3 of the rasTSTP matrix
        normalSTPToRAS = vtk.vtkMatrix3x3()
        for row in range(3):
            for column in range(3):
                normalSTPToRAS.SetElement(row, column,
                                          rasToSTP.GetElement(row, column))
        normalSTPToRAS.Transpose()
        parameters['normalSTPToRAS'] = ''
        for column in range(3):
            for row in range(3):
                # write in column-major order for glsl mat3 constructor
                parameters[
                    'normalSTPToRAS'] += "%f," % normalSTPToRAS.GetElement(
                        row, column)
        parameters['normalSTPToRAS'] = parameters[
            'normalSTPToRAS'][:-1]  # clear trailing comma

        return parameters