Пример #1
0
    def Smooth_Surface(self, surface):
        # Take a vtk surface and run it through the smoothing pipeline

        boneNormals = vtk.vtkPolyDataNormals()
        try:
            boneNormals.SetInputData(surface)
        except:
            boneNormals.SetInputConnection(surface.GetOutputPort())

        boneNormals.Update()

        # Clean the polydata so that the edges are shared!
        cleanPolyData = vtk.vtkCleanPolyData()
        cleanPolyData.SetInputConnection(boneNormals.GetOutputPort())
        cleanPolyData.Update()
        polydata = cleanPolyData.GetOutput()

        if self.smoothing_iterations > 0:
            # Apply laplacian smoothing to the surface
            smoothingFilter = vtk.vtkSmoothPolyDataFilter()
            smoothingFilter.SetInputData(polydata)
            smoothingFilter.SetNumberOfIterations(
                int(self.smoothing_iterations))
            smoothingFilter.SetRelaxationFactor(self.relaxation_factor)
            smoothingFilter.Update()

            polydata = smoothingFilter.GetOutput()

        if self.decimate_surface > 0 and self.decimate_surface < 1:
            # We want to preserve topology (not let any cracks form). This may
            # limit the total reduction possible, which we have specified at 80%.
            deci = vtk.vtkDecimatePro()
            deci.SetInputData(polydata)
            deci.SetTargetReduction(self.decimate_surface)
            deci.PreserveTopologyOn()
            deci.Update()
            polydata = deci.GetOutput()

        # Clean the polydata so that the edges are shared!
        cleanPolyData = vtk.vtkCleanPolyData()
        cleanPolyData.SetInputData(polydata)
        cleanPolyData.Update()
        polydata = cleanPolyData.GetOutput()

        # Generate surface normals to give a better visualization
        normals = vtk.vtkPolyDataNormals()
        normals.SetInputData(polydata)
        normals.Update()
        polydata = normals.GetOutput()

        return polydata
Пример #2
0
  def applyFilters(self, state):

    surface = state.inputModelNode.GetPolyData()

    if state.decimation:
      triangle = vtk.vtkTriangleFilter()
      triangle.SetInput(surface)
      decimation = vtk.vtkDecimatePro()
      decimation.SetInput(triangle.GetOutput())
      decimation.SetTargetReduction(state.reduction)
      decimation.SetBoundaryVertexDeletion(state.boundaryDeletion)
      decimation.PreserveTopologyOn()
      decimation.Update()
      surface = decimation.GetOutput()

    if state.smoothing:
      if state.smoothingMethod == "Laplace":
        smoothing = vtk.vtkSmoothPolyDataFilter()
        smoothing.SetInput(surface)
        smoothing.SetBoundarySmoothing(state.boundarySmoothing)
        smoothing.SetNumberOfIterations(state.laplaceIterations)
        smoothing.SetRelaxationFactor(state.laplaceRelaxation)
        smoothing.Update()
        surface = smoothing.GetOutput()
      elif state.smoothingMethod == "Taubin":
        smoothing = vtk.vtkWindowedSincPolyDataFilter()
        smoothing.SetInput(surface)
        smoothing.SetBoundarySmoothing(state.boundarySmoothing)
        smoothing.SetNumberOfIterations(state.taubinIterations)
        smoothing.SetPassBand(state.taubinPassBand)
        smoothing.Update()
        surface = smoothing.GetOutput()

    if state.normals:
      normals = vtk.vtkPolyDataNormals()
      normals.SetInput(surface)
      normals.AutoOrientNormalsOn()
      normals.SetFlipNormals(state.flipNormals)
      normals.SetSplitting(state.splitting)
      normals.SetFeatureAngle(state.featureAngle)
      normals.ConsistencyOn()
      normals.Update()
      surface = normals.GetOutput()

    if state.cleaner:
      cleaner = vtk.vtkCleanPolyData()
      cleaner.SetInput(surface)
      cleaner.Update()
      surface = cleaner.GetOutput()

    if state.connectivity:
      connectivity = vtk.vtkPolyDataConnectivityFilter()
      connectivity.SetInput(surface)
      connectivity.SetExtractionModeToLargestRegion()
      connectivity.Update()
      surface = connectivity.GetOutput()

    state.outputModelNode.SetAndObservePolyData(surface)

    return True
Пример #3
0
  def applyFilters(self, state):

    surface = state.inputModelNode.GetPolyData()

    if state.decimation:
      triangle = vtk.vtkTriangleFilter()
      triangle.SetInput(surface)
      decimation = vtk.vtkDecimatePro()
      decimation.SetInput(triangle.GetOutput())
      decimation.SetTargetReduction(state.reduction)
      decimation.SetBoundaryVertexDeletion(state.boundaryDeletion)
      decimation.PreserveTopologyOn()
      decimation.Update()
      surface = decimation.GetOutput()

    if state.smoothing:
      if state.smoothingMethod == "Laplace":
        smoothing = vtk.vtkSmoothPolyDataFilter()
        smoothing.SetInput(surface)
        smoothing.SetBoundarySmoothing(state.boundarySmoothing)
        smoothing.SetNumberOfIterations(state.laplaceIterations)
        smoothing.SetRelaxationFactor(state.laplaceRelaxation)
        smoothing.Update()
        surface = smoothing.GetOutput()
      elif state.smoothingMethod == "Taubin":
        smoothing = vtk.vtkWindowedSincPolyDataFilter()
        smoothing.SetInput(surface)
        smoothing.SetBoundarySmoothing(state.boundarySmoothing)
        smoothing.SetNumberOfIterations(state.taubinIterations)
        smoothing.SetPassBand(state.taubinPassBand)
        smoothing.Update()
        surface = smoothing.GetOutput()

    if state.normals:
      normals = vtk.vtkPolyDataNormals()
      normals.SetInput(surface)
      normals.AutoOrientNormalsOn()
      normals.SetFlipNormals(state.flipNormals)
      normals.SetSplitting(state.splitting)
      normals.SetFeatureAngle(state.featureAngle)
      normals.ConsistencyOn()
      normals.Update()
      surface = normals.GetOutput()

    if state.cleaner:
      cleaner = vtk.vtkCleanPolyData()
      cleaner.SetInput(surface)
      cleaner.Update()
      surface = cleaner.GetOutput()

    if state.connectivity:
      connectivity = vtk.vtkPolyDataConnectivityFilter()
      connectivity.SetInput(surface)
      connectivity.SetExtractionModeToLargestRegion()
      connectivity.Update()
      surface = connectivity.GetOutput()

    state.outputModelNode.SetAndObservePolyData(surface)

    return True
    def prepareModel( self, polyData ):
        '''
        '''
        # import the vmtk libraries
        try:
            #from libvtkvmtkComputationalGeometryPython import *
            #from libvtkvmtkMiscPython import *
            import libvtkvmtkComputationalGeometryPython as cg
            import libvtkvmtkMiscPython as m
        except ImportError:
            print "FAILURE: Unable to import the SlicerVmtk libraries!"

        capDisplacement = 0.0

        surfaceCleaner = vtk.vtkCleanPolyData()
        surfaceCleaner.SetInput( polyData )
        surfaceCleaner.Update()

        surfaceTriangulator = vtk.vtkTriangleFilter()
        surfaceTriangulator.SetInput( surfaceCleaner.GetOutput() )
        surfaceTriangulator.PassLinesOff()
        surfaceTriangulator.PassVertsOff()
        surfaceTriangulator.Update()

        # new steps for preparation to avoid problems because of slim models (f.e. at stenosis)
        subdiv = vtk.vtkLinearSubdivisionFilter()
        subdiv.SetInput( surfaceTriangulator.GetOutput() )
        subdiv.SetNumberOfSubdivisions( 1 )
        subdiv.Update()

        smooth = vtk.vtkWindowedSincPolyDataFilter()
        smooth.SetInput( subdiv.GetOutput() )
        smooth.SetNumberOfIterations( 20 )
        smooth.SetPassBand( 0.1 )
        smooth.SetBoundarySmoothing( 1 )
        smooth.Update()

        normals = vtk.vtkPolyDataNormals()
        normals.SetInput( smooth.GetOutput() )
        normals.SetAutoOrientNormals( 1 )
        normals.SetFlipNormals( 0 )
        normals.SetConsistency( 1 )
        normals.SplittingOff()
        normals.Update()

        surfaceCapper = m.vtkvmtkCapPolyData()
        surfaceCapper.SetInput( normals.GetOutput() )
        surfaceCapper.SetDisplacement( capDisplacement )
        surfaceCapper.SetInPlaneDisplacement( capDisplacement )
        surfaceCapper.Update()

        outPolyData = vtk.vtkPolyData()
        outPolyData.DeepCopy( surfaceCapper.GetOutput() )
        outPolyData.Update()

        return outPolyData
    def polydataBoolean(self,
                        polyData1,
                        polyData2,
                        operation,
                        triangleFilter=False,
                        loop=False,
                        clean=True):
        # Subtract/add polyData2 from polyData1
        if (not polyData1) or (not polyData2):
            return polyData1

        booleanFilter = vtk.vtkBooleanOperationPolyDataFilter()
        if loop:
            booleanFilter = vtk.vtkLoopBooleanPolyDataFilter()

        if operation == "difference" or operation == "subtract":
            booleanFilter.SetOperationToDifference()
        elif operation == "union" or operation == "addition":
            booleanFilter.SetOperationToUnion()
        elif operation == "intersection":
            booleanFilter.SetOperationToIntersection()
        else:
            return None

        if triangleFilter:
            triangleFilter1 = vtk.vtkTriangleFilter()
            triangleFilter1.SetInputData(polyData1)
            triangleFilter1.Update()

            triangleFilter2 = vtk.vtkTriangleFilter()
            triangleFilter2.SetInputData(polyData2)
            triangleFilter2.Update()

            booleanFilter.SetInputData(0, triangleFilter1.GetOutput())
            booleanFilter.SetInputData(1, triangleFilter2.GetOutput())
        else:
            booleanFilter.SetInputData(0, polyData1)
            booleanFilter.SetInputData(1, polyData2)

        booleanFilter.Update()

        if clean:
            cleanFilter = vtk.vtkCleanPolyData()
            cleanFilter.SetInputData(booleanFilter.GetOutput())
            cleanFilter.PointMergingOn()
            cleanFilter.Update()
            print("blah")
            return cleanFilter.GetOutput()
        else:
            return booleanFilter.GetOutput()
 def vtkCleanPolyData(self, inputModelNode, tolerance, runtimeLabel):
   runtime = vtk.vtkTimerLog()
   runtime.StartTimer()
   # vtkVertexGlyphFilter
   glyphFilter = vtk.vtkVertexGlyphFilter()
   glyphFilter.SetInputConnection(inputModelNode.GetPolyDataConnection())
   # vtkCleanPolyData
   cleanPolyData = vtk.vtkCleanPolyData()
   cleanPolyData.SetInputConnection(glyphFilter.GetOutputPort())
   cleanPolyData.SetTolerance(tolerance)
   cleanPolyData.Update()
   runtime.StopTimer()
   runtimeLabel.setText('vtkCleanPolyData computed in  %.2f' % runtime.GetElapsedTime() + ' s.')    
   inputModelNode.SetAndObservePolyData(cleanPolyData.GetOutput())
Пример #7
0
 def vtkCleanPolyData(self, inputModelNode, tolerance, runtimeLabel):
     runtime = vtk.vtkTimerLog()
     runtime.StartTimer()
     # vtkVertexGlyphFilter
     glyphFilter = vtk.vtkVertexGlyphFilter()
     glyphFilter.SetInputConnection(inputModelNode.GetPolyDataConnection())
     # vtkCleanPolyData
     cleanPolyData = vtk.vtkCleanPolyData()
     cleanPolyData.SetInputConnection(glyphFilter.GetOutputPort())
     cleanPolyData.SetTolerance(tolerance)
     cleanPolyData.Update()
     runtime.StopTimer()
     runtimeLabel.setText('vtkCleanPolyData computed in  %.2f' %
                          runtime.GetElapsedTime() + ' s.')
     inputModelNode.SetAndObservePolyData(cleanPolyData.GetOutput())
  def GetBoundaryPoints( self, inPolyData ):

    featureEdges = vtk.vtkFeatureEdges()
    featureEdges.FeatureEdgesOff()
    featureEdges.NonManifoldEdgesOff()
    featureEdges.ManifoldEdgesOff()
    featureEdges.BoundaryEdgesOn()
    featureEdges.SetInputData( inPolyData )
    featureEdges.Update()
    
    stripper = vtk.vtkStripper()
    stripper.SetInputData( featureEdges.GetOutput() )
    stripper.Update()
    
    cleaner = vtk.vtkCleanPolyData()
    cleaner.SetInputData( stripper.GetOutput() )
    cleaner.Update()
       
    return cleaner.GetOutput().GetPoints()
Пример #9
0
    def decimateSurface( self, polyData ):
        '''
        '''

        decimationFilter = vtk.vtkDecimatePro()
        decimationFilter.SetInputData( polyData )
        decimationFilter.SetTargetReduction( 0.99 )
        decimationFilter.SetBoundaryVertexDeletion( 0 )
        decimationFilter.PreserveTopologyOn()
        decimationFilter.Update()

        cleaner = vtk.vtkCleanPolyData()
        cleaner.SetInputData( decimationFilter.GetOutput() )
        cleaner.Update()

        triangleFilter = vtk.vtkTriangleFilter()
        triangleFilter.SetInputData( cleaner.GetOutput() )
        triangleFilter.Update()

        outPolyData = vtk.vtkPolyData()
        outPolyData.DeepCopy( triangleFilter.GetOutput() )

        return outPolyData
    def clipSurfaceAtEndPoints(self, networkPolyData, surfacePolyData):
        '''
        Clips the surfacePolyData on the endpoints identified using the networkPolyData.
        
        Returns a tupel of the form [clippedPolyData, endpointsPoints]
        '''
        # import the vmtk libraries
        try:
            from libvtkvmtkComputationalGeometryPython import *
            from libvtkvmtkMiscPython import *
        except ImportError:
            print "FAILURE: Unable to import the SlicerVmtk4 libraries!"

        cleaner = vtk.vtkCleanPolyData()
        cleaner.SetInput(networkPolyData)
        cleaner.Update()
        network = cleaner.GetOutput()
        network.BuildCells()
        network.BuildLinks(0)
        endpointIds = vtk.vtkIdList()

        radiusArray = network.GetPointData().GetArray('Radius')

        endpoints = vtk.vtkPolyData()
        endpointsPoints = vtk.vtkPoints()
        endpointsRadius = vtk.vtkDoubleArray()
        endpointsRadius.SetName('Radius')
        endpoints.SetPoints(endpointsPoints)
        endpoints.GetPointData().AddArray(endpointsRadius)

        radiusFactor = 1.2
        minRadius = 0.01

        for i in range(network.GetNumberOfCells()):
            numberOfCellPoints = network.GetCell(i).GetNumberOfPoints()
            pointId0 = network.GetCell(i).GetPointId(0)
            pointId1 = network.GetCell(i).GetPointId(numberOfCellPoints - 1)

            pointCells = vtk.vtkIdList()
            network.GetPointCells(pointId0, pointCells)
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId(pointId0)
                if pointId == numberOfEndpoints:
                    point = network.GetPoint(pointId0)
                    radius = radiusArray.GetValue(pointId0)
                    radius = max(radius, minRadius)
                    endpointsPoints.InsertNextPoint(point)
                    endpointsRadius.InsertNextValue(radiusFactor * radius)

            pointCells = vtk.vtkIdList()
            network.GetPointCells(pointId1, pointCells)
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId(pointId1)
                if pointId == numberOfEndpoints:
                    point = network.GetPoint(pointId1)
                    radius = radiusArray.GetValue(pointId1)
                    radius = max(radius, minRadius)
                    endpointsPoints.InsertNextPoint(point)
                    endpointsRadius.InsertNextValue(radiusFactor * radius)

        polyBall = vtkvmtkPolyBall()
        polyBall.SetInput(endpoints)
        polyBall.SetPolyBallRadiusArrayName('Radius')

        clipper = vtk.vtkClipPolyData()
        clipper.SetInput(surfacePolyData)
        clipper.SetClipFunction(polyBall)
        clipper.Update()

        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInput(clipper.GetOutput())
        connectivityFilter.ColorRegionsOff()
        connectivityFilter.SetExtractionModeToLargestRegion()
        connectivityFilter.Update()

        clippedSurface = connectivityFilter.GetOutput()

        outPolyData = vtk.vtkPolyData()
        outPolyData.DeepCopy(clippedSurface)
        outPolyData.Update()

        return [outPolyData, endpointsPoints]
Пример #11
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
Пример #13
0
    def clipSurfaceAtEndPoints( self, networkPolyData, surfacePolyData ):
        '''
        Clips the surfacePolyData on the endpoints identified using the networkPolyData.

        Returns a tupel of the form [clippedPolyData, endpointsPoints]
        '''
        # import the vmtk libraries
        try:
            import vtkvmtkComputationalGeometryPython as vtkvmtkComputationalGeometry
            import vtkvmtkMiscPython as vtkvmtkMisc
        except ImportError:
            logging.error("Unable to import the SlicerVmtk libraries")

        cleaner = vtk.vtkCleanPolyData()
        cleaner.SetInputData( networkPolyData )
        cleaner.Update()
        network = cleaner.GetOutput()
        network.BuildCells()
        network.BuildLinks( 0 )
        endpointIds = vtk.vtkIdList()

        radiusArray = network.GetPointData().GetArray( 'Radius' )

        endpoints = vtk.vtkPolyData()
        endpointsPoints = vtk.vtkPoints()
        endpointsRadius = vtk.vtkDoubleArray()
        endpointsRadius.SetName( 'Radius' )
        endpoints.SetPoints( endpointsPoints )
        endpoints.GetPointData().AddArray( endpointsRadius )

        radiusFactor = 1.2
        minRadius = 0.01

        for i in range( network.GetNumberOfCells() ):
            numberOfCellPoints = network.GetCell( i ).GetNumberOfPoints()
            pointId0 = network.GetCell( i ).GetPointId( 0 )
            pointId1 = network.GetCell( i ).GetPointId( numberOfCellPoints - 1 )

            pointCells = vtk.vtkIdList()
            network.GetPointCells( pointId0, pointCells )
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId( pointId0 )
                if pointId == numberOfEndpoints:
                    point = network.GetPoint( pointId0 )
                    radius = radiusArray.GetValue( pointId0 )
                    radius = max( radius, minRadius )
                    endpointsPoints.InsertNextPoint( point )
                    endpointsRadius.InsertNextValue( radiusFactor * radius )

            pointCells = vtk.vtkIdList()
            network.GetPointCells( pointId1, pointCells )
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId( pointId1 )
                if pointId == numberOfEndpoints:
                    point = network.GetPoint( pointId1 )
                    radius = radiusArray.GetValue( pointId1 )
                    radius = max( radius, minRadius )
                    endpointsPoints.InsertNextPoint( point )
                    endpointsRadius.InsertNextValue( radiusFactor * radius )

        polyBall = vtkvmtkComputationalGeometry.vtkvmtkPolyBall()
        #polyBall.SetInputData( endpoints )
        polyBall.SetInput( endpoints )
        polyBall.SetPolyBallRadiusArrayName( 'Radius' )

        clipper = vtk.vtkClipPolyData()
        clipper.SetInputData( surfacePolyData )
        clipper.SetClipFunction( polyBall )
        clipper.Update()

        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInputData( clipper.GetOutput() )
        connectivityFilter.ColorRegionsOff()
        connectivityFilter.SetExtractionModeToLargestRegion()
        connectivityFilter.Update()

        clippedSurface = connectivityFilter.GetOutput()

        outPolyData = vtk.vtkPolyData()
        outPolyData.DeepCopy( clippedSurface )

        return [outPolyData, endpointsPoints]
Пример #14
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
  def run( self, markupNode, depth, fitPlane, flip ):
    """
    Run the actual algorithm
    """
    
    # Get all of the fiducial nodes and convert to vtkPoints
    points = vtk.vtkPoints()
    
    for i in range( 0, markupNode.GetNumberOfFiducials() ):
      currentCoordinates = [ 0, 0, 0 ]
      markupNode.GetNthFiducialPosition( i, currentCoordinates )
      points.InsertNextPoint( currentCoordinates )
      
    # Check that there is non-zero range in all coordinate directions
    pointsBounds = [ 0, 0, 0, 0, 0, 0 ]
    points.GetBounds( pointsBounds )
    if ( pointsBounds[0] == pointsBounds [1] or pointsBounds[2] == pointsBounds [3] or pointsBounds[4] == pointsBounds [5] ):
      print "Tissue Model Creator: Points have no extent in one or more coordinate directions."
      return False
      
    # Create a polydata object from the points
    # The reversiness doesn't matter - we will fix it later if it os wrong
    if ( fitPlane ):
      surfacePolyData = self.PointsToPlanePolyData( points, True )
    else:
      surfacePolyData = self.PointsToSurfacePolyData( points, True )
      
    surfaceCleaner = vtk.vtkCleanPolyData()
    surfaceCleaner.SetInputData( surfacePolyData )
    surfaceCleaner.Update()
    surfacePolyData = surfaceCleaner.GetOutput()
    
    mean = self.CalculateMean( points )
    
    surfaceBase = [ 0, 0, 0 ]
    surfaceDir1 = [ 0, 0, 0 ]
    surfaceDir2 = [ 0, 0, 0 ]
    surfaceNormal = [ 0, 0, 0 ]
    self.CalculatePlane( surfacePolyData.GetPoints(), surfaceBase, surfaceDir1, surfaceDir2, surfaceNormal )
    
    if ( flip == True ):
      surfaceNormal[ 0 ] = - surfaceNormal[ 0 ]
      surfaceNormal[ 1 ] = - surfaceNormal[ 1 ]
      surfaceNormal[ 2 ] = - surfaceNormal[ 2 ]
    
    extremePointIndex = self.FindExtremePoint( surfacePolyData.GetPoints(), surfaceBase, surfaceNormal )
    reverse = self.ReverseNormals( extremePointIndex, surfacePolyData, surfaceNormal )
    
    # Reverse the normals if necessary
    reverseFilter = vtk.vtkReverseSense()
    reverseFilter.SetInputData( surfacePolyData )
    reverseFilter.SetReverseCells( reverse )
    reverseFilter.SetReverseNormals( reverse )
    reverseFilter.Update()
    surfacePolyData = reverseFilter.GetOutput()
    
    untransDeepPolyData = vtk.vtkPolyData()
    untransDeepPolyData.DeepCopy( surfacePolyData )
    
    # Make the normals opposite the surface's normals
    reverseFilter = vtk.vtkReverseSense()
    reverseFilter.SetInputData( untransDeepPolyData )
    reverseFilter.SetReverseCells( True )
    reverseFilter.SetReverseNormals( True )
    reverseFilter.Update()
    untransDeepPolyData = reverseFilter.GetOutput()
    
    deepTransform = vtk.vtkTransform()
    deepTransform.Translate( depth * surfaceNormal[0], depth * surfaceNormal[1], depth * surfaceNormal[2] )  
    deepTransformFilter = vtk.vtkTransformPolyDataFilter()
    deepTransformFilter.SetInputData( untransDeepPolyData )
    deepTransformFilter.SetTransform( deepTransform )
    deepTransformFilter.Update()
    
    deepPolyData = deepTransformFilter.GetOutput()

    
    surfaceHullPoints = self.GetBoundaryPoints( surfacePolyData )
    
    deepHullPoints = self.GetBoundaryPoints( deepPolyData )
    
    # Apparently, the joining needs an offset for the plane, but not for the surface reconstruction
    if ( fitPlane ):
      jointHullPolyData = self.JoinBoundaryPoints( surfaceHullPoints, deepHullPoints, 1 )
    else:
      jointHullPolyData = self.JoinBoundaryPoints( surfaceHullPoints, deepHullPoints, 0 )
    
    
    # Append all of the polydata together
    tissuePolyDataAppend = vtk.vtkAppendPolyData()
    tissuePolyDataAppend.AddInputData( surfacePolyData )
    tissuePolyDataAppend.AddInputData( deepPolyData )
    tissuePolyDataAppend.AddInputData( jointHullPolyData )   
    tissuePolyDataAppend.Update()

    # Clean up so the surface is closed
    tissueCleaner = vtk.vtkCleanPolyData()
    tissueCleaner.SetInputData( tissuePolyDataAppend.GetOutput() )
    tissueCleaner.Update()
    
    tissueModelPolyData = tissueCleaner.GetOutput()
    
    # Add the data to a model 
    tissueModel = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLModelNode" )
    slicer.mrmlScene.AddNode( tissueModel )
    tissueModel.SetName( "TissueModel" )
    tissueModel.SetAndObservePolyData( tissueModelPolyData )    
    tissueModel.SetScene( slicer.mrmlScene )
    
    # Finally display the model
    tissueModelDisplay = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLModelDisplayNode" )
    slicer.mrmlScene.AddNode( tissueModelDisplay )
    tissueModel.SetAndObserveDisplayNodeID( tissueModelDisplay.GetID() )
    tissueModelDisplay.SetScene( slicer.mrmlScene )
    tissueModelDisplay.SetInputPolyDataConnection( tissueModel.GetPolyDataConnection() )


    # Check to make sure the model is a closed surface
    edgesFilter = vtk.vtkFeatureEdges()
    edgesFilter.FeatureEdgesOff()
    edgesFilter.BoundaryEdgesOn()
    edgesFilter.NonManifoldEdgesOn()
    edgesFilter.SetInputData( tissueModel.GetPolyData() )
    edgesFilter.Update()
    
    if ( edgesFilter.GetOutput().GetNumberOfCells() != 0 ):
      print "Tissue Model Creator: Surface is not closed."
      return False
      
    return True
  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