Exemplo n.º 1
0
  def ComputeMeanDistance(self, inputSourceModel, inputTargetModel, transform ):
    sourcePolyData = inputSourceModel.GetPolyData()
    targetPolyData = inputTargetModel.GetPolyData()

    cellId = vtk.mutable(0)
    subId = vtk.mutable(0)
    dist2 = vtk.mutable(0.0)
    locator = vtk.vtkCellLocator()
    locator.SetDataSet( targetPolyData )
    locator.SetNumberOfCellsPerBucket( 1 )
    locator.BuildLocator()
    
    totalDistance = 0.0

    sourcePoints = sourcePolyData.GetPoints()
    n = sourcePoints.GetNumberOfPoints()
    m = vtk.vtkMath()
    for sourcePointIndex in xrange(n):
      sourcePointPos = [0, 0, 0]
      sourcePoints.GetPoint( sourcePointIndex, sourcePointPos )
      transformedSourcePointPos = [0, 0, 0, 1]
      #transform.GetTransformToParent().TransformVector( sourcePointPos, transformedSourcePointPos )
      sourcePointPos.append(1)
      transform.GetTransformToParent().MultiplyPoint( sourcePointPos, transformedSourcePointPos )      
      #transformedPoints.InsertNextPoint( transformedSourcePointPos )
      surfacePoint = [0, 0, 0]
      transformedSourcePointPos.pop()
      locator.FindClosestPoint( transformedSourcePointPos, surfacePoint, cellId, subId, dist2 )
      totalDistance = totalDistance + math.sqrt(dist2)

    return ( totalDistance / n )
Exemplo n.º 2
0
  def ComputeMeanDistance(self, inputSourceModel, inputTargetModel, transform ):
    sourcePolyData = inputSourceModel.GetPolyData()
    targetPolyData = inputTargetModel.GetPolyData()

    cellId = vtk.mutable(0)
    subId = vtk.mutable(0)
    dist2 = vtk.mutable(0.0)
    locator = vtk.vtkCellLocator()
    locator.SetDataSet( targetPolyData )
    locator.SetNumberOfCellsPerBucket( 1 )
    locator.BuildLocator()

    totalDistance = 0.0

    sourcePoints = sourcePolyData.GetPoints()
    n = sourcePoints.GetNumberOfPoints()
    m = vtk.vtkMath()
    for sourcePointIndex in range(n):
      sourcePointPos = [0, 0, 0]
      sourcePoints.GetPoint( sourcePointIndex, sourcePointPos )
      transformedSourcePointPos = [0, 0, 0, 1]
      #transform.GetTransformToParent().TransformVector( sourcePointPos, transformedSourcePointPos )
      sourcePointPos.append(1)
      transform.GetTransformToParent().MultiplyPoint( sourcePointPos, transformedSourcePointPos )
      #transformedPoints.InsertNextPoint( transformedSourcePointPos )
      surfacePoint = [0, 0, 0]
      transformedSourcePointPos.pop()
      locator.FindClosestPoint( transformedSourcePointPos, surfacePoint, cellId, subId, dist2 )
      totalDistance = totalDistance + math.sqrt(dist2)

    return ( totalDistance / n )
Exemplo n.º 3
0
 def computeCameraUpDirectionInRAS(self, toolCameraToRASTransform, cameraOriginInRASMm, focalPointInRASMm):
   upDirectionInRAS = [0,0,0] # placeholder values
   if (self.forcedUpDirection == True):
     math = vtk.vtkMath()
     # cross product of forwardDirectionInRAS vector with upInRAS vector is the rightDirectionInRAS vector
     upInRAS = self.upInRAS
     forwardDirectionInRAS = self.computeCameraProjectionDirectionInRAS(cameraOriginInRASMm, focalPointInRASMm)
     rightDirectionInRAS = [0,0,0] # placeholder values
     math.Cross(forwardDirectionInRAS,upInRAS,rightDirectionInRAS)
     numberDimensions = 3;
     lengthMm = math.Norm(rightDirectionInRAS,numberDimensions)
     epsilon = 0.0001
     if (lengthMm < epsilon): # must check for this case
       logging.warning("Warning: length of cross product in computeCameraUpDirectionInRAS is zero. Workaround used")
       backupUpDirectionInRAS = [1,1,1] # if the previous cross product was zero, then this shouldn't be
       math.Normalize(backupUpDirectionInRAS)
       upInRAS = backupUpDirectionInRAS
       math.Cross(forwardDirectionInRAS,upInRAS,rightDirectionInRAS)
     math.Normalize(rightDirectionInRAS)
     # now compute the cross product between the rightDirectionInRAS and forwardDirectionInRAS directions to get a corrected up vector
     upDirectionInRAS = [0,0,0] # placeholder values
     math.Cross(rightDirectionInRAS,forwardDirectionInRAS,upDirectionInRAS)
     math.Normalize(upDirectionInRAS)
   else:
     upDirectionInToolCamera = [0,1,0] # standard up direction in OpenGL
     dummyPoint = [0,0,0] # Needed by the TransformVectorAtPoint function
     toolCameraToRASTransform.TransformVectorAtPoint(dummyPoint,upDirectionInToolCamera,upDirectionInRAS)
   return upDirectionInRAS
Exemplo n.º 4
0
  def ComputeMeanDistance(self, inputFiducials, inputModel, transform):
    surfacePoints = vtk.vtkPoints()
    cellId = vtk.mutable(0)
    subId = vtk.mutable(0)
    dist2 = vtk.mutable(0.0)
    locator = vtk.vtkCellLocator()
    locator.SetDataSet(inputModel.GetPolyData())
    locator.SetNumberOfCellsPerBucket(1)
    locator.BuildLocator()
    totalDistance = 0.0

    n = inputFiducials.GetNumberOfFiducials()
    m = vtk.vtkMath()
    for fiducialIndex in range(0, n):
      originalPoint = [0, 0, 0]
      inputFiducials.GetNthFiducialPosition(fiducialIndex, originalPoint)
      transformedPoint = [0, 0, 0, 1]
      #transform.GetTransformToParent().TransformVector(originalPoint, transformedPoint)
      originalPoint.append(1)
      transform.GetTransformToParent().MultiplyPoint(originalPoint, transformedPoint)
      #transformedPoints.InsertNextPoint(transformedPoint)
      surfacePoint = [0, 0, 0]
      transformedPoint.pop()
      locator.FindClosestPoint(transformedPoint, surfacePoint, cellId, subId, dist2)
      totalDistance = totalDistance + math.sqrt(dist2)

    return (totalDistance / n)
  def ComputeMeanDistance(self, inputFiducials, inputModel, transform ):
    surfacePoints = vtk.vtkPoints()
    cellId = vtk.mutable(0)
    subId = vtk.mutable(0)
    dist2 = vtk.mutable(0.0)
    locator = vtk.vtkCellLocator()
    locator.SetDataSet( inputModel.GetPolyData() )
    locator.SetNumberOfCellsPerBucket( 1 )
    locator.BuildLocator()
    totalDistance = 0.0

    n = inputFiducials.GetNumberOfFiducials()
    m = vtk.vtkMath()
    for fiducialIndex in range( 0, n ):
      originalPoint = [0, 0, 0]
      inputFiducials.GetNthFiducialPosition( fiducialIndex, originalPoint )
      transformedPoint = [0, 0, 0, 1]
      #transform.GetTransformToParent().TransformVector( originalPoint, transformedPoint )
      originalPoint.append(1)
      transform.GetTransformToParent().MultiplyPoint( originalPoint, transformedPoint )
      #transformedPoints.InsertNextPoint( transformedPoint )
      surfacePoint = [0, 0, 0]
      transformedPoint.pop()
      locator.FindClosestPoint( transformedPoint, surfacePoint, cellId, subId, dist2 )
      totalDistance = totalDistance + math.sqrt(dist2)

    return ( totalDistance / n )
Exemplo n.º 6
0
  def updateSlice(self, point, angle):
    print self.polydataPoints
    if self.polydataPoints:
      pos = self.polydataPoints.GetPoint(point)
      norm = [0.0, 0.0, 0.0]
      v1 = [0.0, 0.0, 0.0]
      v2 = [0.0, 0.0, 0.0]

      if point < self.numberOfPoints-1:
        pos1 = self.polydataPoints.GetPoint(point+1)
        norm = [pos1[0]-pos[0], pos1[1]-pos[1], pos1[2]-pos[2]]
      else:
        pos1 = self.polydataPoints.GetPoint(point-1)
        norm = [-(pos1[0]-pos[0]), -(pos1[1]-pos[1]), -(pos1[2]-pos[2])]

      math = vtk.vtkMath()

      normLength = math.Normalize(norm)
      norm[0] /= normLength
      norm[1] /= normLength
      norm[2] /= normLength

      math.Perpendiculars(norm,v1,v2,angle*math.Pi()/180)

      self.redViewer.SetSliceToRASByNTP(norm[0],norm[1],norm[2],v1[0],v1[1],v1[2],pos[0],pos[1],pos[2],0)
  def getClustersCenterOfMass(self,fiducialList,sortClusters=False):
    clusterMassCenter = {}
    sortedClusterMassCenter = {}
    clusterFiducials = {}
    fiducialPosition = [0.0, 0.0, 0.0]
    clusterPointPosition = [0.0, 0.0, 0.0]
    mathDist = vtk.vtkMath()
    distanceThreshold = 40

    for pt in range(fiducialList.GetNumberOfFiducials()):
      belongToExistingCluster = False
      fiducialList.GetNthFiducialPosition(pt,fiducialPosition)

      # Compute distance from fiducial to the first point of all clusters
      for cluster in range(len(clusterFiducials)):
        fiducialList.GetNthFiducialPosition(clusterFiducials[cluster][0],clusterPointPosition)
        dist = math.sqrt(mathDist.Distance2BetweenPoints(clusterPointPosition,fiducialPosition))

        # Fiducial belong to current cluster. Add it to the list of point of the current cluster.
        if dist < distanceThreshold:
          clusterFiducials[cluster].append(pt);
          belongToExistingCluster = True
          break

      # Fiducial does not belong to any cluster. Create a new one.
      if not belongToExistingCluster:
        clusterFiducials[len(clusterFiducials)] = [pt]

    # Compute center of mass of each cluster
    for cluster in range(len(clusterFiducials)):
      centerOfMass = [0.0, 0.0, 0.0]
      for pts in range(len(clusterFiducials[cluster])):
        tmpPos = [0.0, 0.0, 0.0]
        fiducialList.GetNthFiducialPosition(clusterFiducials[cluster][pts],tmpPos)
        centerOfMass[0] = centerOfMass[0] + tmpPos[0]
        centerOfMass[1] = centerOfMass[1] + tmpPos[1]
        centerOfMass[2] = centerOfMass[2] + tmpPos[2]

      centerOfMass[0] = centerOfMass[0] / len(clusterFiducials[cluster])
      centerOfMass[1] = centerOfMass[1] / len(clusterFiducials[cluster])
      centerOfMass[2] = centerOfMass[2] / len(clusterFiducials[cluster])

      clusterMassCenter[cluster] = [centerOfMass[0], centerOfMass[1], centerOfMass[2]]

    # Order cluster list by number of fiducials in it
    if sortClusters:
      sortedClusters = sorted(clusterFiducials, key=lambda i: int(len(clusterFiducials[i])))
      for cluster in range(len(clusterMassCenter)):
        sortedClusterMassCenter[cluster] = [clusterMassCenter[sortedClusters[cluster]][0],
                                            clusterMassCenter[sortedClusters[cluster]][1],
                                            clusterMassCenter[sortedClusters[cluster]][2]]
      return sortedClusterMassCenter

    return clusterMassCenter
Exemplo n.º 8
0
 def computeCameraProjectionDirectionInRAS(self, cameraOriginInRASMm, focalPointInRASMm):
   math = vtk.vtkMath()
   directionFromOriginToFocalPointRAS = [0,0,0] # placeholder values
   math.Subtract(focalPointInRASMm,cameraOriginInRASMm,directionFromOriginToFocalPointRAS)
   math.Normalize(directionFromOriginToFocalPointRAS)
   numberDimensions = 3;
   lengthMm = math.Norm(directionFromOriginToFocalPointRAS,numberDimensions)
   epsilon = 0.0001
   if (lengthMm < epsilon):
     logging.warning("Warning: computeCameraProjectionDirectionInRAS() is computing a zero vector. Check target model? Using [0,0,-1] as target direction.")
     directionFromOriginToFocalPointRAS = [0,0,-1];
   return directionFromOriginToFocalPointRAS
Exemplo n.º 9
0
  def __init__(self, entryPointFiducialListNode, targetFiducialListNode, shape, shapeRadius, shapeHeight, shapeVolume, ablationZoneColor):
    
    entryPointFid = entryPointFiducialListNode
    targetFid = targetFiducialListNode
    
    scene = slicer.mrmlScene
    
    
    if (shape == 'sphere'):
      source = vtk.vtkSphereSource()
      source.SetRadius(shapeRadius)
      source.Update()
    elif (shape == 'cylinder'):
      source = vtk.vtkCylinderSource()
      source.SetRadius(shapeRadius)
      source.SetHeight(shapeHeight)
      source.Update()
    elif (shape == 'ellipsoid'):
      source = vtk.vtkSphereSource()
      source.SetRadius(shapeRadius)
      source.Update()
    else:
      source = vtk.vtkSphereSource()
      source.SetRadius(shapeRadius)
      source.Update()
    
    
    # get coordinates from current entry point fiducial
    currentEntryPointFiducialCoordinatesRAS = [0, 0, 0]
    
    entryPointFid.GetFiducialCoordinates(currentEntryPointFiducialCoordinatesRAS)
    
    currentTargetFiducialCoordinatesRAS = [0, 0, 0]
    
    targetFid.GetFiducialCoordinates(currentTargetFiducialCoordinatesRAS)
    
    translationTarget = [currentTargetFiducialCoordinatesRAS[0], currentTargetFiducialCoordinatesRAS[1], currentTargetFiducialCoordinatesRAS[2]]

    # Generate a random start and end point
    random.seed(8775070)
    startPoint = [0 for i in range(3)]
    startPoint[0] = currentEntryPointFiducialCoordinatesRAS[0]
    startPoint[1] = currentEntryPointFiducialCoordinatesRAS[1]
    startPoint[2] = currentEntryPointFiducialCoordinatesRAS[2]
    endPoint = [0 for i in range(3)]
    endPoint[0] = currentTargetFiducialCoordinatesRAS[0]
    endPoint[1] = currentTargetFiducialCoordinatesRAS[1]
    endPoint[2] = currentTargetFiducialCoordinatesRAS[2]
     
    # Compute a basis
    normalizedX = [0 for i in range(3)]
    normalizedY = [0 for i in range(3)]
    normalizedZ = [0 for i in range(3)]
     
    # The X axis is a vector from start to end
    math = vtk.vtkMath()
    math.Subtract(endPoint, startPoint, normalizedX)
    # length = math.Norm(normalizedX)
    math.Normalize(normalizedX)
    
    # The Z axis is an arbitrary vector cross X
    arbitrary = [0 for i in range(3)]
    arbitrary[0] = random.uniform(-10,10)
    arbitrary[1] = random.uniform(-10,10)
    arbitrary[2] = random.uniform(-10,10)
    math.Cross(normalizedX, arbitrary, normalizedZ)
    math.Normalize(normalizedZ)
    
    # The Y axis is Z cross X
    math.Cross(normalizedZ, normalizedX, normalizedY)
    matrix = vtk.vtkMatrix4x4()
     
    # Create the direction cosine matrix
    matrix.Identity()
    for i in range(3):
      matrix.SetElement(i, 0, normalizedX[i])
      matrix.SetElement(i, 1, normalizedY[i])
      matrix.SetElement(i, 2, normalizedZ[i])
      matrix.SetElement(i, 3, currentTargetFiducialCoordinatesRAS[i])
      
    # Apply the transforms
    transform = vtk.vtkTransform()
    transform.Concatenate(matrix)
    transform.RotateZ(90)
    
    '''
    ps = vtk.vtkProgrammableSource()
    
    import math 
    numPts = 80
    polyLinePoints = vtk.vtkPoints() 
    polyLinePoints.SetNumberOfPoints(numPts) 
    R=1.0 
    for i in range(0,numPts):
      x = R*math.cos(i*2*math.pi/numPts) 
      y = R*math.sin(i*2*math.pi/numPts) 
      polyLinePoints.InsertPoint(i, x, y, 0)
    aPolyLine1 = vtk.vtkPolyLine() 
    aPolyLine1.GetPointIds().SetNumberOfIds(numPts+1) 
    for i in range(0,numPts):
      aPolyLine1.GetPointIds().SetId(i,i) 
    # add one more cell at the end to close the circle on itself 
    aPolyLine1.GetPointIds().SetId(numPts, 0)
    aPolyLineGrid = ps.GetOutput()
    aPolyLineGrid.Allocate(1,1)
    aPolyLineGrid.InsertNextCell(aPolyLine1.GetCellType(), aPolyLine1.GetPointIds())
    aPolyLineGrid.SetPoints(polyLinePoints)
    '''
    
    '''
    #This script generates a helix double.
    #This is intended as the script of a 'Programmable Source'
    import math
     
    ps = vtk.vtkSphereSource()
    
    
    numPts = 80 # Points along each Helix
    length = 8 # Length of each Helix
    rounds = 3 # Number of times around
    phase_shift = math.pi/1.5 # Phase shift between Helixes
     
    #Get a vtk.PolyData object for the output
    pdo = ps.GetOutput()
    print "before"
    print pdo
    
    #This will store the points for the Helix
    newPts = vtk.vtkPoints()
    for i in range(0, numPts):
       #Generate Points for first Helix
       x = i*length/numPts
       y = math.sin(i*rounds*2*math.pi/numPts)
       z = math.cos(i*rounds*2*math.pi/numPts)
       newPts.InsertPoint(i, x,y,z)
     
       #Generate Points for second Helix. Add a phase offset to y and z.
       y = math.sin(i*rounds*2*math.pi/numPts+phase_shift)
       z = math.cos(i*rounds*2*math.pi/numPts+phase_shift)
       #Offset Helix 2 pts by 'numPts' to keep separate from Helix 1 Pts
       newPts.InsertPoint(i+numPts, x,y,z)
     
    #Add the points to the vtkPolyData object
    pdo.SetPoints(newPts)
     
    #Make two vtkPolyLine objects to hold curve construction data
    aPolyLine1 = vtk.vtkPolyLine()
    aPolyLine2 = vtk.vtkPolyLine()
     
    #Indicate the number of points along the line
    aPolyLine1.GetPointIds().SetNumberOfIds(numPts)
    aPolyLine2.GetPointIds().SetNumberOfIds(numPts)
    for i in range(0,numPts):
       #First Helix - use the first set of points
       aPolyLine1.GetPointIds().SetId(i, i)
       #Second Helix - use the second set of points
       #(Offset the point reference by 'numPts').
       aPolyLine2.GetPointIds().SetId(i,i+numPts)
     
    #Allocate the number of 'cells' that will be added. 
    #Two 'cells' for the Helix curves, and one 'cell'
    #for every 3rd point along the Helixes.
    links = range(0,numPts,3)
    pdo.Allocate(2+len(links), 1)
     
    #Add the poly line 'cell' to the vtkPolyData object.
    pdo.InsertNextCell(aPolyLine1.GetCellType(), aPolyLine1.GetPointIds())
    pdo.InsertNextCell(aPolyLine2.GetCellType(), aPolyLine2.GetPointIds())
     
    for i in links:
       #Add a line connecting the two Helixes.
       aLine = vtk.vtkLine()
       aLine.GetPointIds().SetId(0, i)
       aLine.GetPointIds().SetId(1, i+numPts)
       pdo.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds())
       
    print "after"
    print pdo
    '''    
    # Create model node
    lesionModel = slicer.vtkMRMLModelNode()
    lesionModel.SetScene(scene)
    lesionModel.SetName("Ablationzone-%s" % targetFid.GetName())
    lesionModel.SetAndObservePolyData(source.GetOutput())
    self.lesionModel = lesionModel
    # Create display node
    lesionModelDisplay = slicer.vtkMRMLModelDisplayNode()
    lesionModelDisplay.SetColor(ablationZoneColor)
    lesionModelDisplay.SetOpacity(0.4)
    lesionModelDisplay.SliceIntersectionVisibilityOn()
    
    lesionModelDisplay.SetScene(scene)
    scene.AddNode(lesionModelDisplay)
    lesionModel.SetAndObserveDisplayNodeID(lesionModelDisplay.GetID())

    
    # Add to scene
    lesionModelDisplay.SetPolyData(source.GetOutput())
    self.lesionModelDisplay = lesionModelDisplay
    self.lesionModel= lesionModel
    
    scene.AddNode(lesionModel)
    
    # Create ablationZoneTransform node
    ablationZoneTransform = slicer.vtkMRMLLinearTransformNode()
    ablationZoneTransform.SetName('AblationZoneTransform-%s' % targetFid.GetName())
    
    scene.AddNode(ablationZoneTransform)
    
    ablationZoneTransform.ApplyTransformMatrix(transform.GetMatrix())
    
    lesionModel.SetAndObserveTransformNodeID(ablationZoneTransform.GetID())
    
    self.ablationZoneTransform = ablationZoneTransform
Exemplo n.º 10
0
    def run(self, inputModel, sModel, seedList):
        """
    Run the actual algorithm
    """

        self.delayDisplay('Running the aglorithm')

        tri = vtk.vtkDelaunay3D()
        tri.SetInputData(sModel.GetPolyData())

        elev = vtk.vtkElevationFilter()
        elev.SetInputConnection(tri.GetOutput())

        implicitDataSet = vtk.vtkImplicitDataSet()
        implicitDataSet.SetDataSet(elev.GetOutput())

        triangle = vtk.vtkTriangleFilter()
        triangle.SetInputData(inputModel.GetPolyData())
        triangle.Update()

        computeNormals = vtk.vtkPolyDataNormals()
        computeNormals.SetInputData(triangle.GetOutput())
        computeNormals.ComputeCellNormalsOn()
        computeNormals.Update()

        clip = vtk.vtkClipPolyData()
        clip.SetInputData(computeNormals.GetOutput())
        clip.SetClipFunction(implicitDataSet)
        clip.InsideOutOff()
        clip.Update()

        clean = vtk.vtkCleanPolyData()
        clean.SetInputData(clip.GetOutput())
        clean.Update()

        polydata = clean.GetOutput()

        cellData = polydata.GetCellData()
        normals = cellData.GetNormals()

        meanNormal = [0, 0, 0]
        nOfTuples = normals.GetNumberOfTuples()

        for cellIndex in range(0, nOfTuples):
            cellNormal = [0, 0, 0]
            cell = polydata.GetCell(cellIndex)

            normals.GetTuple(cellIndex, cellNormal)
            meanNormal[0] = meanNormal[0] + cellNormal[0]
            meanNormal[1] = meanNormal[1] + cellNormal[1]
            meanNormal[2] = meanNormal[2] + cellNormal[2]

        meanNormal[0] = meanNormal[0] / nOfTuples
        meanNormal[1] = meanNormal[1] / nOfTuples
        meanNormal[2] = meanNormal[2] / nOfTuples

        print("Normal: " + str(meanNormal))

        seed1 = [0, 0, 0]
        seedList.GetNthFiducialPosition(0, seed1)
        vector = [
            seed1[0] + 50 * meanNormal[0], seed1[1] + 50 * meanNormal[1],
            seed1[2] + 50 * meanNormal[2]
        ]
        seedList.AddFiducialFromArray(vector)

        # Calculate perpendicular vectors
        v1 = [0, 0, 0]
        v2 = [0, 0, 0]

        math = vtk.vtkMath()
        math.Perpendiculars(meanNormal, v2, v1, 0)

        # Normalize vectors
        math.Normalize(meanNormal)
        math.Normalize(v1)
        math.Normalize(v2)

        # create matrix4x4
        transform = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLLinearTransformNode')
        slicer.mrmlScene.AddNode(transform)
        matrix = transform.GetMatrixTransformToParent()

        matrix.SetElement(0, 0, v1[0])
        matrix.SetElement(1, 0, v1[1])
        matrix.SetElement(2, 0, v1[2])
        matrix.SetElement(3, 0, 0.0)

        matrix.SetElement(0, 1, meanNormal[0])
        matrix.SetElement(1, 1, meanNormal[1])
        matrix.SetElement(2, 1, meanNormal[2])
        matrix.SetElement(3, 1, 0.0)

        matrix.SetElement(0, 2, v2[0])
        matrix.SetElement(1, 2, v2[1])
        matrix.SetElement(2, 2, v2[2])
        matrix.SetElement(3, 2, 0.0)

        matrix.SetElement(0, 3, seed1[0])
        matrix.SetElement(1, 3, seed1[1])
        matrix.SetElement(2, 3, seed1[2])
        matrix.SetElement(3, 3, 1.0)

        return True
  def run(self,inputModel,sModel,seedList):
    """
    Run the actual algorithm
    """

    self.delayDisplay('Running the aglorithm')

    tri = vtk.vtkDelaunay3D()
    tri.SetInputData(sModel.GetPolyData())

    elev = vtk.vtkElevationFilter()
    elev.SetInputConnection(tri.GetOutput())

    implicitDataSet = vtk.vtkImplicitDataSet()
    implicitDataSet.SetDataSet(elev.GetOutput())
    
    triangle = vtk.vtkTriangleFilter()
    triangle.SetInputData(inputModel.GetPolyData())
    triangle.Update()

    computeNormals = vtk.vtkPolyDataNormals()
    computeNormals.SetInputData(triangle.GetOutput())
    computeNormals.ComputeCellNormalsOn()
    computeNormals.Update()

    clip = vtk.vtkClipPolyData()
    clip.SetInputData(computeNormals.GetOutput())
    clip.SetClipFunction(implicitDataSet)
    clip.InsideOutOff()
    clip.Update()

    clean = vtk.vtkCleanPolyData()
    clean.SetInputData(clip.GetOutput())
    clean.Update()

    polydata = clean.GetOutput()

    cellData = polydata.GetCellData()
    normals = cellData.GetNormals()

    meanNormal = [0,0,0]
    nOfTuples = normals.GetNumberOfTuples()

    for cellIndex in range(0, nOfTuples):
      cellNormal = [0,0,0]
      cell = polydata.GetCell(cellIndex)
      
      normals.GetTuple(cellIndex, cellNormal)
      meanNormal[0] = meanNormal[0] + cellNormal[0]
      meanNormal[1] = meanNormal[1] + cellNormal[1]
      meanNormal[2] = meanNormal[2] + cellNormal[2]
        
    meanNormal[0] = meanNormal[0] / nOfTuples
    meanNormal[1] = meanNormal[1] / nOfTuples
    meanNormal[2] = meanNormal[2] / nOfTuples

    print("Normal: " + str(meanNormal))

    seed1 = [0,0,0]
    seedList.GetNthFiducialPosition(0,seed1)
    vector = [seed1[0]+50*meanNormal[0],
              seed1[1]+50*meanNormal[1],
              seed1[2]+50*meanNormal[2]]
    seedList.AddFiducialFromArray(vector)

    # Calculate perpendicular vectors
    v1 = [0,0,0]
    v2 = [0,0,0]

    math = vtk.vtkMath()
    math.Perpendiculars(meanNormal, v2, v1, 0)

    # Normalize vectors
    math.Normalize(meanNormal)
    math.Normalize(v1)
    math.Normalize(v2)

    # create matrix4x4
    transform = slicer.mrmlScene.CreateNodeByClass('vtkMRMLLinearTransformNode') 
    slicer.mrmlScene.AddNode(transform)
    matrix = transform.GetMatrixTransformToParent()
    
    matrix.SetElement(0,0,v1[0])
    matrix.SetElement(1,0,v1[1])
    matrix.SetElement(2,0,v1[2])
    matrix.SetElement(3,0,0.0)

    matrix.SetElement(0,1,meanNormal[0])
    matrix.SetElement(1,1,meanNormal[1])
    matrix.SetElement(2,1,meanNormal[2])
    matrix.SetElement(3,1,0.0)

    matrix.SetElement(0,2,v2[0])
    matrix.SetElement(1,2,v2[1])
    matrix.SetElement(2,2,v2[2])
    matrix.SetElement(3,2,0.0)

    matrix.SetElement(0,3,seed1[0])
    matrix.SetElement(1,3,seed1[1])
    matrix.SetElement(2,3,seed1[2])
    matrix.SetElement(3,3,1.0)


    return True
Exemplo n.º 12
0
    def run(self, inputModel, spherePosition, sphereRadius, outputTransform):
        """
    Run the actual algorithm
    """

        if not self.isValidInputOutputData(inputModel, outputTransform):
            slicer.util.errorDisplay(
                'Input model is the same as sphere model. Choose a different input model.'
            )
            return False

        logging.info('Processing started')

        # Convert sphere model to an implicit dataset to clip input model with it
        sphere = vtk.vtkSphere()
        sphere.SetCenter(spherePosition)
        sphere.SetRadius(sphereRadius)

        # Clip and clean input model
        triangle = vtk.vtkTriangleFilter()
        triangle.SetInputData(inputModel.GetPolyData())
        triangle.Update()

        clip = vtk.vtkClipPolyData()
        clip.SetInputData(triangle.GetOutput())
        clip.SetClipFunction(sphere)
        clip.InsideOutOn()
        clip.Update()

        clean = vtk.vtkCleanPolyData()
        clean.SetInputConnection(clip.GetOutputPort())
        clean.Update()

        # Compute average normal
        clippedModel = clip.GetOutput()
        cellsNormal = clippedModel.GetPointData().GetNormals()

        averageNormal = [0.0, 0.0, 0.0]
        nOfNormals = 0

        for cellIndex in range(0, cellsNormal.GetNumberOfTuples()):
            cellNormal = [0.0, 0.0, 0.0]
            cellsNormal.GetTuple(cellIndex, cellNormal)

            if not (math.isnan(cellNormal[0]) or math.isnan(cellNormal[1])
                    or math.isnan(cellNormal[2])):
                averageNormal[0] = averageNormal[0] + cellNormal[0]
                averageNormal[1] = averageNormal[1] + cellNormal[1]
                averageNormal[2] = averageNormal[2] + cellNormal[2]
                nOfNormals = nOfNormals + 1

        # Compute perpendicular vectors
        v1 = [0.0, 0.0, 0.0]
        v2 = [0.0, 0.0, 0.0]

        vtkmath = vtk.vtkMath()
        #vtkmath.Perpendiculars(averageNormal, v2, v1, 0)
        self.calculatePerpendicularVectors(averageNormal, v2, v1)

        # Normalize vectors
        vtkmath.Normalize(averageNormal)
        vtkmath.Normalize(v1)
        vtkmath.Normalize(v2)

        # Create Matrix4x4
        outputMatrix = vtk.vtkMatrix4x4()

        outputMatrix.SetElement(0, 0, v1[0])
        outputMatrix.SetElement(1, 0, v1[1])
        outputMatrix.SetElement(2, 0, v1[2])
        outputMatrix.SetElement(3, 0, 0.0)

        outputMatrix.SetElement(0, 1, averageNormal[0])
        outputMatrix.SetElement(1, 1, averageNormal[1])
        outputMatrix.SetElement(2, 1, averageNormal[2])
        outputMatrix.SetElement(3, 1, 0.0)

        outputMatrix.SetElement(0, 2, v2[0])
        outputMatrix.SetElement(1, 2, v2[1])
        outputMatrix.SetElement(2, 2, v2[2])
        outputMatrix.SetElement(3, 2, 0.0)

        outputMatrix.SetElement(0, 3, spherePosition[0])
        outputMatrix.SetElement(1, 3, spherePosition[1])
        outputMatrix.SetElement(2, 3, spherePosition[2])
        outputMatrix.SetElement(3, 3, 1.0)

        outputTransform.SetMatrixTransformToParent(outputMatrix)

        logging.info('Processing completed')

        return True
Exemplo n.º 13
0
    def calculatePerpendicularVectors(self, initialVector, v1, v2):
        vtkmath = vtk.vtkMath()

        tmpZvector = [0.0, 0.0, 1.0]
        vtkmath.Cross(initialVector, tmpZvector, v1)
        vtkmath.Cross(initialVector, v1, v2)
Exemplo n.º 14
0
  def __init__(self, entryPointFiducialListNode, targetFiducialListNode, length, diameter, probeText, probeColor):
    
    entryPointFid = entryPointFiducialListNode
    targetFid = targetFiducialListNode
    scene = slicer.mrmlScene
    
    #Create an probe.
    probe = vtk.vtkCylinderSource()
    probe.SetHeight(length)
    probe.SetRadius(diameter / 2)
    
    pos = [0 for i in range(3)]
    
    # get coordinates from current entry point fiducial
    currentEntryPointFiducialCoordinatesRAS = [0, 0, 0]
    
    entryPointFid.GetFiducialCoordinates(currentEntryPointFiducialCoordinatesRAS)
    
    currentTargetFiducialCoordinatesRAS = [0, 0, 0]
    
    targetFid.GetFiducialCoordinates(currentTargetFiducialCoordinatesRAS)
    
    # pos is the vector that describes the distance between the target and the entry point
    for i in range(3):
      pos[i] = currentTargetFiducialCoordinatesRAS[i] - currentEntryPointFiducialCoordinatesRAS[i]
      
    pointsDistance = sqrt(pow(pos[0], 2) + pow(pos[1], 2) + pow(pos[2], 2))
    
    # len is the vector that describes the length of the probe
    len = [0 for i in range(3)]
    for i in range(3):
      len[i] = length / pointsDistance * pos[i]
      
    translationTarget = [currentTargetFiducialCoordinatesRAS[0] - len[0] / 2, currentTargetFiducialCoordinatesRAS[1] - len[1] / 2, currentTargetFiducialCoordinatesRAS[2] - len[2] / 2]

    # Generate a random start and end point
    random.seed(8775070)
    startPoint = [0 for i in range(3)]
    startPoint[0] = currentEntryPointFiducialCoordinatesRAS[0]
    startPoint[1] = currentEntryPointFiducialCoordinatesRAS[1]
    startPoint[2] = currentEntryPointFiducialCoordinatesRAS[2]
    endPoint = [0 for i in range(3)]
    endPoint[0] = currentTargetFiducialCoordinatesRAS[0]
    endPoint[1] = currentTargetFiducialCoordinatesRAS[1]
    endPoint[2] = currentTargetFiducialCoordinatesRAS[2]
     
    # Compute a basis
    normalizedX = [0 for i in range(3)]
    normalizedY = [0 for i in range(3)]
    normalizedZ = [0 for i in range(3)]
     
    # The X axis is a vector from start to end
    math = vtk.vtkMath()
    math.Subtract(endPoint, startPoint, normalizedX)
    # length = math.Norm(normalizedX)
    math.Normalize(normalizedX)
    
    # The Z axis is an arbitrary vector cross X
    arbitrary = [0 for i in range(3)]
    arbitrary[0] = random.uniform(-10,10)
    arbitrary[1] = random.uniform(-10,10)
    arbitrary[2] = random.uniform(-10,10)
    math.Cross(normalizedX, arbitrary, normalizedZ)
    math.Normalize(normalizedZ)
    
    # The Y axis is Z cross X
    math.Cross(normalizedZ, normalizedX, normalizedY)
    matrix = vtk.vtkMatrix4x4()
     
    # Create the direction cosine matrix
    matrix.Identity()
    for i in range(3):
      matrix.SetElement(i, 0, normalizedX[i])
      matrix.SetElement(i, 1, normalizedY[i])
      matrix.SetElement(i, 2, normalizedZ[i])
     
    # Apply the transforms
    transform = vtk.vtkTransform()
    transform.Translate(translationTarget)
    transform.Concatenate(matrix)
    transform.RotateZ(90)
    
    
    # Create model node
    probeModel = slicer.vtkMRMLModelNode()
    probeModel.SetScene(scene)
    probeModel.SetName(probeText + "-%s" % targetFid.GetName())
    probeModel.SetAndObservePolyData(probe.GetOutput())

    # Create display node
    probeModelDisplay = slicer.vtkMRMLModelDisplayNode()
    
    probeModelDisplay.SetColor(probeColor)
    
    probeModelDisplay.SetOpacity(1)
    probeModelDisplay.SliceIntersectionVisibilityOn()
    
    probeModelDisplay.SetScene(scene)
    scene.AddNode(probeModelDisplay)
    probeModel.SetAndObserveDisplayNodeID(probeModelDisplay.GetID())

    # Add to scene
    probeModelDisplay.SetPolyData(probe.GetOutput())
    
    scene.AddNode(probeModel)
    
    
    # Create probeTransform node
    probeTransform = slicer.vtkMRMLLinearTransformNode()
    probeTransform.SetName(probeText + 'Transform-%s' % entryPointFid.GetName())
    
    scene.AddNode(probeTransform)
    
    probeTransform.ApplyTransformMatrix(transform.GetMatrix())
    
    probeModel.SetAndObserveTransformNodeID(probeTransform.GetID())
  def PointsToPlanePolyData( self, inPoints, reverse ):

    # Create the oriented bounding box
    # This gives us one plane on the bounding box, not the plane of best fit
    corner = [ 0, 0, 0 ]
    maxVector = [ 0, 0, 0 ]
    midVector = [ 0, 0, 0 ]
    minVector = [ 0, 0, 0 ]
    size = [ 0, 0, 0 ]    
    obb = vtk.vtkOBBTree()
    obb.ComputeOBB( inPoints, corner, maxVector, midVector, minVector, size )
    
    # Calculate the mean of the points on the plane
    base = self.CalculateMean( inPoints )
    relBase = [ 0, 0, 0 ]
    # Find the projection of the mean point in the minVector direction
    vtk.vtkMath().Subtract( base, corner, relBase )
    normal = minVector[:]
    vtk.vtkMath().Normalize( normal )
    dot = vtk.vtkMath().Dot( relBase, normal )
    dot = 0
    proj = normal[:]
    vtk.vtkMath().MultiplyScalar( proj, dot )
    
    print dot
    
    # Find the points on the plane
    origin = [ 0, 0, 0 ]
    point1 = [ 0, 0, 0 ]
    point2 = [ 0, 0, 0 ]
    vtk.vtkMath().Add( corner, proj, origin )
    vtk.vtkMath().Add( origin, maxVector, point1 )
    vtk.vtkMath().Add( origin, midVector, point2 )
    
    # Construct the plane
    plane = vtk.vtkPlaneSource()
    plane.SetOrigin( origin )
    plane.SetPoint1( point1 )
    plane.SetPoint2( point2 )
    plane.Update()
    
    return plane.GetOutput()
  def run(self, inputModel, spherePosition, sphereRadius, outputTransform):
    """
    Run the actual algorithm
    """

    if not self.isValidInputOutputData(inputModel, outputTransform):
      slicer.util.errorDisplay('Input model is the same as sphere model. Choose a different input model.')
      return False

    logging.info('Processing started')

    # Convert sphere model to an implicit dataset to clip input model with it
    sphere = vtk.vtkSphere()
    sphere.SetCenter(spherePosition)
    sphere.SetRadius(sphereRadius)

    # Clip and clean input model
    triangle = vtk.vtkTriangleFilter()
    triangle.SetInputData(inputModel.GetPolyData())
    triangle.Update()

    clip = vtk.vtkClipPolyData()
    clip.SetInputData(triangle.GetOutput())
    clip.SetClipFunction(sphere)
    clip.InsideOutOn()
    clip.Update()

    clean = vtk.vtkCleanPolyData()
    clean.SetInputConnection(clip.GetOutputPort())
    clean.Update()

    # Compute average normal
    clippedModel = clip.GetOutput()
    cellsNormal = clippedModel.GetPointData().GetNormals()
    
    averageNormal = [0.0, 0.0, 0.0]
    nOfNormals = 0;

    for cellIndex in range(0, cellsNormal.GetNumberOfTuples()):
      cellNormal = [0.0, 0.0, 0.0]
      cellsNormal.GetTuple(cellIndex, cellNormal)
      
      if not(math.isnan(cellNormal[0]) or math.isnan(cellNormal[1]) or math.isnan(cellNormal[2])):
        averageNormal[0] = averageNormal[0] + cellNormal[0]
        averageNormal[1] = averageNormal[1] + cellNormal[1]
        averageNormal[2] = averageNormal[2] + cellNormal[2]
        nOfNormals = nOfNormals + 1

    # Compute perpendicular vectors
    v1 = [0.0, 0.0, 0.0]
    v2 = [0.0, 0.0, 0.0]
    
    vtkmath = vtk.vtkMath()
    #vtkmath.Perpendiculars(averageNormal, v2, v1, 0)
    self.calculatePerpendicularVectors(averageNormal, v2, v1)

    # Normalize vectors
    vtkmath.Normalize(averageNormal)
    vtkmath.Normalize(v1)
    vtkmath.Normalize(v2)
    
    # Create Matrix4x4
    outputMatrix = vtk.vtkMatrix4x4()
    
    outputMatrix.SetElement(0,0,v1[0])
    outputMatrix.SetElement(1,0,v1[1])
    outputMatrix.SetElement(2,0,v1[2])
    outputMatrix.SetElement(3,0,0.0)

    outputMatrix.SetElement(0,1,averageNormal[0])
    outputMatrix.SetElement(1,1,averageNormal[1])
    outputMatrix.SetElement(2,1,averageNormal[2])
    outputMatrix.SetElement(3,1,0.0)

    outputMatrix.SetElement(0,2,v2[0])
    outputMatrix.SetElement(1,2,v2[1])
    outputMatrix.SetElement(2,2,v2[2])
    outputMatrix.SetElement(3,2,0.0)

    outputMatrix.SetElement(0,3,spherePosition[0])
    outputMatrix.SetElement(1,3,spherePosition[1])
    outputMatrix.SetElement(2,3,spherePosition[2])
    outputMatrix.SetElement(3,3,1.0)

    outputTransform.SetMatrixTransformToParent(outputMatrix)

    logging.info('Processing completed')

    return True
  def calculatePerpendicularVectors(self, initialVector, v1, v2):
    vtkmath = vtk.vtkMath()

    tmpZvector = [0.0, 0.0, 1.0]
    vtkmath.Cross(initialVector, tmpZvector, v1)
    vtkmath.Cross(initialVector, v1, v2)