def generateResectionVolume(self, fiducialNode, modelNode):
        if (fiducialNode != None):
            self.FiducialNode = fiducialNode
            self.PolyData = vtk.vtkPolyData()
            self.updatePoints()

            self.Delaunay = vtk.vtkDelaunay3D()
            if (vtk.VTK_MAJOR_VERSION <= 5):
                self.Delaunay.SetInput(self.PolyData)
            else:
                self.Delaunay.SetInputData(self.PolyData)
            self.Delaunay.Update()

            self.SurfaceFilter = vtk.vtkDataSetSurfaceFilter()
            self.SurfaceFilter.SetInputConnection(
                self.Delaunay.GetOutputPort())
            self.SurfaceFilter.Update()

            self.Smoother = vtk.vtkButterflySubdivisionFilter()
            self.Smoother.SetInputConnection(
                self.SurfaceFilter.GetOutputPort())
            self.Smoother.SetNumberOfSubdivisions(3)
            self.Smoother.Update()

            if modelNode.GetDisplayNodeID() == None:
                modelDisplayNode = slicer.mrmlScene.CreateNodeByClass(
                    "vtkMRMLModelDisplayNode")
                modelDisplayNode.SetColor(0, 0, 1)  # Blue
                modelDisplayNode.BackfaceCullingOff()
                modelDisplayNode.SetOpacity(0.3)  # Between 0-1, 1 being opaque
                slicer.mrmlScene.AddNode(modelDisplayNode)
                modelNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID())

            if (vtk.VTK_MAJOR_VERSION <= 5):
                modelNode.SetAndObservePolyData(self.Smoother.GetOutput())
            else:
                modelNode.SetPolyDataConnection(self.Smoother.GetOutputPort())
            modelNode.Modified()

            self.tag = self.FiducialNode.AddObserver(
                'ModifiedEvent', self.updateResectionVolume)
Пример #2
0
  def generateResectionVolume(self, fiducialNode, modelNode):
    if (fiducialNode != None):
      self.FiducialNode = fiducialNode
      self.PolyData = vtk.vtkPolyData()
      self.updatePoints()


      self.Delaunay = vtk.vtkDelaunay3D()
      if (vtk.VTK_MAJOR_VERSION <= 5):
        self.Delaunay.SetInput(self.PolyData)
      else:
        self.Delaunay.SetInputData(self.PolyData)
      self.Delaunay.Update()

      self.SurfaceFilter = vtk.vtkDataSetSurfaceFilter()
      self.SurfaceFilter.SetInputConnection(self.Delaunay.GetOutputPort())
      self.SurfaceFilter.Update()

      self.Smoother = vtk.vtkButterflySubdivisionFilter()
      self.Smoother.SetInputConnection(self.SurfaceFilter.GetOutputPort())
      self.Smoother.SetNumberOfSubdivisions(3)
      self.Smoother.Update()

      if modelNode.GetDisplayNodeID() == None:
        modelDisplayNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLModelDisplayNode")
        modelDisplayNode.SetColor(0,0,1) # Blue
        modelDisplayNode.BackfaceCullingOff()
        modelDisplayNode.SetOpacity(0.3) # Between 0-1, 1 being opaque
        slicer.mrmlScene.AddNode(modelDisplayNode)
        modelNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID())

      if (vtk.VTK_MAJOR_VERSION <= 5):
        modelNode.SetAndObservePolyData(self.Smoother.GetOutput())
      else:
        modelNode.SetPolyDataConnection(self.Smoother.GetOutputPort())
      modelNode.Modified()

      self.tag = self.FiducialNode.AddObserver('ModifiedEvent', self.updateResectionVolume)
Пример #3
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
Пример #5
0
    def updateModelFromMarkup(self, inputMarkup, outputModel):
        """
    Update model to enclose all points in the input markup list
    """

        # Delaunay triangulation is robust and creates nice smooth surfaces from a small number of points,
        # however it can only generate convex surfaces robustly.
        useDelaunay = True

        # Create polydata point set from markup points

        points = vtk.vtkPoints()
        cellArray = vtk.vtkCellArray()

        numberOfPoints = inputMarkup.GetNumberOfFiducials()

        # Surface generation algorithms behave unpredictably when there are not enough points
        # return if there are very few points
        if useDelaunay:
            if numberOfPoints < 3:
                return
        else:
            if numberOfPoints < 10:
                return

        points.SetNumberOfPoints(numberOfPoints)
        new_coord = [0.0, 0.0, 0.0]

        for i in range(numberOfPoints):
            inputMarkup.GetNthFiducialPosition(i, new_coord)
            points.SetPoint(i, new_coord)

        cellArray.InsertNextCell(numberOfPoints)
        for i in range(numberOfPoints):
            cellArray.InsertCellPoint(i)

        pointPolyData = vtk.vtkPolyData()
        pointPolyData.SetLines(cellArray)
        pointPolyData.SetPoints(points)

        # Create surface from point set

        if useDelaunay:

            delaunay = vtk.vtkDelaunay3D()
            delaunay.SetInputData(pointPolyData)

            surfaceFilter = vtk.vtkDataSetSurfaceFilter()
            surfaceFilter.SetInputConnection(delaunay.GetOutputPort())

            smoother = vtk.vtkButterflySubdivisionFilter()
            smoother.SetInputConnection(surfaceFilter.GetOutputPort())
            smoother.SetNumberOfSubdivisions(3)
            smoother.Update()

            outputModel.SetPolyDataConnection(smoother.GetOutputPort())

        else:

            surf = vtk.vtkSurfaceReconstructionFilter()
            surf.SetInputData(pointPolyData)
            surf.SetNeighborhoodSize(20)
            surf.SetSampleSpacing(
                80
            )  # lower value follows the small details more closely but more dense pointset is needed as input

            cf = vtk.vtkContourFilter()
            cf.SetInputConnection(surf.GetOutputPort())
            cf.SetValue(0, 0.0)

            # Sometimes the contouring algorithm can create a volume whose gradient
            # vector and ordering of polygon (using the right hand rule) are
            # inconsistent. vtkReverseSense cures this problem.
            reverse = vtk.vtkReverseSense()
            reverse.SetInputConnection(cf.GetOutputPort())
            reverse.ReverseCellsOff()
            reverse.ReverseNormalsOff()

            outputModel.SetPolyDataConnection(reverse.GetOutputPort())

        # Create default model display node if does not exist yet
        if not outputModel.GetDisplayNode():
            modelDisplayNode = slicer.mrmlScene.CreateNodeByClass(
                "vtkMRMLModelDisplayNode")
            modelDisplayNode.SetColor(0, 0, 1)  # Blue
            modelDisplayNode.BackfaceCullingOff()
            modelDisplayNode.SliceIntersectionVisibilityOn()
            modelDisplayNode.SetOpacity(0.3)  # Between 0-1, 1 being opaque
            slicer.mrmlScene.AddNode(modelDisplayNode)
            outputModel.SetAndObserveDisplayNodeID(modelDisplayNode.GetID())

        outputModel.GetDisplayNode().SliceIntersectionVisibilityOn()

        outputModel.Modified()
Пример #6
0
    def createTumorFromMarkups(self):
        logging.debug('createTumorFromMarkups')
        #self.tumorMarkups_Needle.SetDisplayVisibility(0)

        # Create polydata point set from markup points
        points = vtk.vtkPoints()
        cellArray = vtk.vtkCellArray()

        numberOfPoints = self.tumorMarkups_Needle.GetNumberOfFiducials()

        if numberOfPoints > 0:
            self.deleteLastFiducialButton.setEnabled(True)
            self.deleteAllFiducialsButton.setEnabled(True)
            self.deleteLastFiducialDuringNavigationButton.setEnabled(True)

        # Surface generation algorithms behave unpredictably when there are not enough points
        # return if there are very few points
        if numberOfPoints < 1:
            return

        points.SetNumberOfPoints(numberOfPoints)
        new_coord = [0.0, 0.0, 0.0]

        for i in range(numberOfPoints):
            self.tumorMarkups_Needle.GetNthFiducialPosition(i, new_coord)
            points.SetPoint(i, new_coord)

        cellArray.InsertNextCell(numberOfPoints)
        for i in range(numberOfPoints):
            cellArray.InsertCellPoint(i)

        pointPolyData = vtk.vtkPolyData()
        pointPolyData.SetLines(cellArray)
        pointPolyData.SetPoints(points)

        delaunay = vtk.vtkDelaunay3D()

        if numberOfPoints < 10:
            logging.debug("use glyphs")
            sphere = vtk.vtkCubeSource()
            glyph = vtk.vtkGlyph3D()
            glyph.SetInputData(pointPolyData)
            glyph.SetSourceConnection(sphere.GetOutputPort())
            #glyph.SetVectorModeToUseNormal()
            #glyph.SetScaleModeToScaleByVector()
            #glyph.SetScaleFactor(0.25)
            delaunay.SetInputConnection(glyph.GetOutputPort())
        else:
            delaunay.SetInputData(pointPolyData)

        surfaceFilter = vtk.vtkDataSetSurfaceFilter()
        surfaceFilter.SetInputConnection(delaunay.GetOutputPort())

        smoother = vtk.vtkButterflySubdivisionFilter()
        smoother.SetInputConnection(surfaceFilter.GetOutputPort())
        smoother.SetNumberOfSubdivisions(3)
        smoother.Update()

        forceConvexShape = True

        if (forceConvexShape == True):
            delaunaySmooth = vtk.vtkDelaunay3D()
            delaunaySmooth.SetInputData(smoother.GetOutput())
            delaunaySmooth.Update()

            smoothSurfaceFilter = vtk.vtkDataSetSurfaceFilter()
            smoothSurfaceFilter.SetInputConnection(
                delaunaySmooth.GetOutputPort())
            self.tumorModel_Needle.SetPolyDataConnection(
                smoothSurfaceFilter.GetOutputPort())
        else:
            self.tumorModel_Needle.SetPolyDataConnection(
                smoother.GetOutputPort())

        self.tumorModel_Needle.Modified()
Пример #7
0
    def createTumorFromMarkups(self):
        logging.debug("createTumorFromMarkups")
        # self.tumorMarkups_Needle.SetDisplayVisibility(0)

        # Create polydata point set from markup points
        points = vtk.vtkPoints()
        cellArray = vtk.vtkCellArray()

        numberOfPoints = self.tumorMarkups_Needle.GetNumberOfFiducials()

        if numberOfPoints > 0:
            self.deleteLastFiducialButton.setEnabled(True)
            self.deleteAllFiducialsButton.setEnabled(True)
            self.deleteLastFiducialDuringNavigationButton.setEnabled(True)

        # Surface generation algorithms behave unpredictably when there are not enough points
        # return if there are very few points
        if numberOfPoints < 1:
            return

        points.SetNumberOfPoints(numberOfPoints)
        new_coord = [0.0, 0.0, 0.0]

        for i in range(numberOfPoints):
            self.tumorMarkups_Needle.GetNthFiducialPosition(i, new_coord)
            points.SetPoint(i, new_coord)

        cellArray.InsertNextCell(numberOfPoints)
        for i in range(numberOfPoints):
            cellArray.InsertCellPoint(i)

        pointPolyData = vtk.vtkPolyData()
        pointPolyData.SetLines(cellArray)
        pointPolyData.SetPoints(points)

        delaunay = vtk.vtkDelaunay3D()

        if numberOfPoints < 10:
            logging.debug("use glyphs")
            sphere = vtk.vtkCubeSource()
            glyph = vtk.vtkGlyph3D()
            glyph.SetInputData(pointPolyData)
            glyph.SetSourceConnection(sphere.GetOutputPort())
            # glyph.SetVectorModeToUseNormal()
            # glyph.SetScaleModeToScaleByVector()
            # glyph.SetScaleFactor(0.25)
            delaunay.SetInputConnection(glyph.GetOutputPort())
        else:
            delaunay.SetInputData(pointPolyData)

        surfaceFilter = vtk.vtkDataSetSurfaceFilter()
        surfaceFilter.SetInputConnection(delaunay.GetOutputPort())

        smoother = vtk.vtkButterflySubdivisionFilter()
        smoother.SetInputConnection(surfaceFilter.GetOutputPort())
        smoother.SetNumberOfSubdivisions(3)
        smoother.Update()

        forceConvexShape = True

        if forceConvexShape == True:
            delaunaySmooth = vtk.vtkDelaunay3D()
            delaunaySmooth.SetInputData(smoother.GetOutput())
            delaunaySmooth.Update()

            smoothSurfaceFilter = vtk.vtkDataSetSurfaceFilter()
            smoothSurfaceFilter.SetInputConnection(delaunaySmooth.GetOutputPort())
            self.tumorModel_Needle.SetPolyDataConnection(smoothSurfaceFilter.GetOutputPort())
        else:
            self.tumorModel_Needle.SetPolyDataConnection(smoother.GetOutputPort())

        self.tumorModel_Needle.Modified()