Example #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
  def runLabelWise(self, targetLabelNode, obstacleModelNode, skinModelNode):
    """
    Run label-wise analysis
    """

    poly = skinModelNode.GetPolyData()
    polyDataNormals = vtk.vtkPolyDataNormals()
    polyDataNormals.SetInput(poly)
    polyDataNormals.ComputeCellNormalsOn()
    polyDataNormals.Update()
    polyData = polyDataNormals.GetOutput()
    
    bspTree = vtk.vtkModifiedBSPTree()
    bspTree.SetDataSet(obstacleModelNode.GetPolyData())
    bspTree.BuildLocator()

    trans = vtk.vtkMatrix4x4()
    targetLabelNode.GetIJKToRASMatrix(trans)
    pos = [0.0, 0.0, 0.0, 0.0]

    imageData = targetLabelNode.GetImageData()
    (x0, x1, y0, y1, z0, z1) = imageData.GetExtent()
    for z in range(z0, z1+1):
      for y in range(y0, y1+1):
    	for x in range(x0, x1+1):
          if imageData.GetScalarComponentAsDouble(x, y, z, 0) > 0:
            trans.MultiplyPoint([x, y, z, 1.0], pos);
            (score, mind, mindp) = self.calcApproachScore(pos[0:3], polyData, bspTree, None)
            imageData.SetScalarComponentFromDouble(x, y, z, 0, score*100.0+1.0)
            #print ("Index(%f, %f, %f)  -> RAS(%f, %f, %f)" % (x, y, z, pos[0], pos[1], pos[2]))
            #print ("Approach Score (<accessible area> / (<accessible area> + <inaccessible area>)) = %f" % (score))
            
    return True
Example #3
0
    def runPointWise(self, targetPointNode, obstacleModelNode, skinModelNode):
        """
    Run point-wise analysis
    """

        print("runPointWise()")
        tPoint = targetPointNode.GetMarkupPointVector(0, 0)
        pTarget = [tPoint[0], tPoint[1], tPoint[2]]
        poly = skinModelNode.GetPolyData()
        polyDataNormals = vtk.vtkPolyDataNormals()
        polyDataNormals.SetInput(poly)
        polyDataNormals.ComputeCellNormalsOn()
        polyDataNormals.Update()
        polyData = polyDataNormals.GetOutput()

        bspTree = vtk.vtkModifiedBSPTree()
        bspTree.SetDataSet(obstacleModelNode.GetPolyData())
        bspTree.BuildLocator()

        (score, mind, mindp) = self.calcApproachScore(pTarget, polyData,
                                                      bspTree, skinModelNode)

        print(
            "Approach Score (<accessible area> / (<accessible area> + <inaccessible area>)) = %f"
            % (score))
        print("Minmum Distance = %f" % (mind))

        return (score, mind, mindp)
  def runPointWise(self, targetPointNode, obstacleModelNode, skinModelNode):
    """
    Run point-wise analysis
    """

    print ("runPointWise()")
    tPoint = targetPointNode.GetMarkupPointVector(0, 0)
    pTarget = [tPoint[0], tPoint[1], tPoint[2]]
    poly = skinModelNode.GetPolyData()
    polyDataNormals = vtk.vtkPolyDataNormals()
    polyDataNormals.SetInput(poly)
    polyDataNormals.ComputeCellNormalsOn()
    polyDataNormals.Update()
    polyData = polyDataNormals.GetOutput()

    bspTree = vtk.vtkModifiedBSPTree()
    bspTree.SetDataSet(obstacleModelNode.GetPolyData())
    bspTree.BuildLocator()

    (score, mind, mindp) = self.calcApproachScore(pTarget, polyData, bspTree, skinModelNode)

    print ("Approach Score (<accessible area> / (<accessible area> + <inaccessible area>)) = %f" % (score))
    print ("Minmum Distance = %f" % (mind))

    return (score, mind, mindp)
Example #5
0
    def runLabelWise(self, targetLabelNode, obstacleModelNode, skinModelNode):
        """
    Run label-wise analysis
    """

        poly = skinModelNode.GetPolyData()
        polyDataNormals = vtk.vtkPolyDataNormals()
        polyDataNormals.SetInput(poly)
        polyDataNormals.ComputeCellNormalsOn()
        polyDataNormals.Update()
        polyData = polyDataNormals.GetOutput()

        bspTree = vtk.vtkModifiedBSPTree()
        bspTree.SetDataSet(obstacleModelNode.GetPolyData())
        bspTree.BuildLocator()

        trans = vtk.vtkMatrix4x4()
        targetLabelNode.GetIJKToRASMatrix(trans)
        pos = [0.0, 0.0, 0.0, 0.0]

        imageData = targetLabelNode.GetImageData()
        (x0, x1, y0, y1, z0, z1) = imageData.GetExtent()
        for z in range(z0, z1 + 1):
            for y in range(y0, y1 + 1):
                for x in range(x0, x1 + 1):
                    if imageData.GetScalarComponentAsDouble(x, y, z, 0) > 0:
                        trans.MultiplyPoint([x, y, z, 1.0], pos)
                        (score, mind, mindp) = self.calcApproachScore(
                            pos[0:3], polyData, bspTree, None)
                        imageData.SetScalarComponentFromDouble(
                            x, y, z, 0, score * 100.0 + 1.0)
                        #print ("Index(%f, %f, %f)  -> RAS(%f, %f, %f)" % (x, y, z, pos[0], pos[1], pos[2]))
                        #print ("Approach Score (<accessible area> / (<accessible area> + <inaccessible area>)) = %f" % (score))

        return True
Example #6
0
    def runPointWise(self, targetPointANode, obstacleModelNode, skinModelNode):
        """
    Run point-wise analysis
    """

        print("runPointWise()")
        #tPointA = targetPointANode.GetMarkupPointVector(0, 0)
        #pTargetA = [tPointA[0], tPointA[1], tPointA[2]]
        #tPointB = targetPointBNode.GetMarkupPointVector(0, 0)
        #pTargetB = [tPointB[0], tPointB[1], tPointB[2]]
        #tPointC = targetPointCNode.GetMarkupPointVector(0, 0)
        #pTargetC = [tPointC[0], tPointC[1], tPointC[2]]

        poly = skinModelNode.GetPolyData()
        polyDataNormals = vtk.vtkPolyDataNormals()
        polyDataNormals.SetInputData(poly)
        polyDataNormals.ComputeCellNormalsOn()
        polyDataNormals.Update()
        polyData = polyDataNormals.GetOutput()

        bspTree = vtk.vtkModifiedBSPTree()
        bspTree.SetDataSet(obstacleModelNode.GetPolyData())
        bspTree.BuildLocator()

        #(score, mind, mindp) = self.calcApproachScore(pTargetA, pTargetB, pTargetC, polyData, bspTree, skinModelNode)
        #(score, mind, mindp) = self.calcApproachScore(pTargetA, polyData, bspTree, skinModelNode)
        (score, mind, mindp) = self.calcApproachScore(targetPointANode,
                                                      polyData, bspTree,
                                                      skinModelNode)

        print("Approach Score (<accessible area>) = %f" % (score))
        print("Minmum Distance = %f" % (mind))

        return (score, mind, mindp)
    def GenerateMould(self, facePolydata, distanceFromMask, ROI, tubePolydata, clippedFace):
        ROIExtents = self.utility.GetROIExtents(ROI)
        outerFaceImplicitFunction = vtk.vtkImplicitModeller()
        outerFaceImplicitFunction.SetInputConnection(facePolydata.GetOutputPort())
        outerFaceImplicitFunction.SetSampleDimensions(70, 70, 70)
        outerFaceImplicitFunction.SetMaximumDistance(distanceFromMask)
        outerFaceImplicitFunction.SetModelBounds(ROIExtents)
        outerFaceImplicitFunction.SetProcessModeToPerVoxel()
        outerMaskContourFunction = vtk.vtkContourFilter()
        # TODO Find out the the allowed thinkness of the plastic
        THICKNESS = 3
        outerMaskContourFunction.SetValue(0, THICKNESS)
        outerMaskContourFunction.SetInputConnection(outerFaceImplicitFunction.GetOutputPort())

        outerFaceNormalsFunction = vtk.vtkPolyDataNormals()
        outerFaceNormalsFunction.AutoOrientNormalsOn()
        outerFaceNormalsFunction.AddInputConnection(outerMaskContourFunction.GetOutputPort())
        # Subtract the Tubes from the mask
        subtractionFilter1 = vtk.vtkBooleanOperationPolyDataFilter()
        subtractionFilter1.SetOperationToDifference()
        subtractionFilter1.SetInputConnection(0, outerFaceNormalsFunction.GetOutputPort())
        subtractionFilter1.SetInputConnection(1, tubePolydata.GetOutputPort())
        # Subtract the inner face from the outer face to make the mask
        subtractionFilter2 = vtk.vtkBooleanOperationPolyDataFilter()
        subtractionFilter2.SetOperationToDifference()
        subtractionFilter2.SetInputConnection(0, subtractionFilter1.GetOutputPort())
        subtractionFilter2.SetInputConnection(1, clippedFace.GetOutputPort())
        x = self.utility.DisplayPolyData("Mask", subtractionFilter2.GetOutput())
        x.SetColor(0.8, 0.8, 0.8)
        x.SetOpacity(1)
Example #8
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
Example #9
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 calculateNormals(polydata, flip=False):
    normalsFilter = vtk.vtkPolyDataNormals()
    normalsFilter.SetInputData(polydata)
    normalsFilter.AutoOrientNormalsOn()
    if flip:
        normalsFilter.FlipNormalsOn()
    normalsFilter.Update()
    return normalsFilter.GetOutput()
Example #11
0
    def MinimumDistanceMask(self,
                            vtkAlgorythmObject,
                            distanceFromMask,
                            ROI,
                            ruler,
                            isBubble=False):
        """ Takes an algorythm object which is will send through a pipeline to 
    create a mask defining the minimum distance value from the skin surface
    returns an algorythm object as well to preform GetOutput() -> polydata
    or GetOutputPort() -> algorythm
    see MinimumDistanceMask.pdf 
    """
        if distanceFromMask < 2:
            print "WARNING: MouldLogic: MinimumDistanceMask implicit",
            "modeling is very unstable below 1.5 , mask may degrade",
            "and lines will become discontinuous."
        Extents = self.utility.GetROIExtents(ROI)
        if (isBubble):
            Extents = self.utility.ExpandExtents(Extents, 100)
        implicitModeller = vtk.vtkImplicitModeller()
        implicitModeller.SetInputConnection(vtkAlgorythmObject.GetOutputPort())
        implicitModeller.SetMaximumDistance(distanceFromMask)
        implicitModeller.SetModelBounds(Extents)
        implicitModeller.AdjustBoundsOn()
        implicitModeller.SetAdjustBounds(10)  # Removes the boundary effects
        implicitModeller.CappingOff(
        )  # Important to create disjoint inner and outer masks
        implicitModeller.SetProcessModeToPerVoxel()
        implicitModeller.Update()

        contourFilter = vtk.vtkContourFilter()
        contourFilter.SetValue(0, distanceFromMask)
        contourFilter.SetInputConnection(implicitModeller.GetOutputPort())
        contourFilter.Update()

        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.FlipNormalsOn()
        normalsFunction.AddInputConnection(contourFilter.GetOutputPort())
        normalsFunction.Update()

        implicitBoxRegion = vtk.vtkBox()
        implicitBoxRegion.SetBounds(Extents)
        clipper2 = vtk.vtkClipPolyData()
        clipper2.InsideOutOn()  # Clip the regions outside of implicit function
        clipper2.SetInputConnection(normalsFunction.GetOutputPort())
        clipper2.SetClipFunction(implicitBoxRegion)
        clipper2.Update()

        closestPoint = [0, 0, 0]
        ruler.GetPosition1(closestPoint)
        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInputConnection(clipper2.GetOutputPort())
        connectivityFilter.SetExtractionModeToClosestPointRegion()
        connectivityFilter.SetClosestPoint(closestPoint)
        connectivityFilter.Update()

        return connectivityFilter.GetOutput()
    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 autoOrientNormals(self, model):
     normals = vtk.vtkPolyDataNormals()
     normals.SetAutoOrientNormals(True)
     normals.SetFlipNormals(False)
     normals.SetSplitting(False)
     normals.ConsistencyOn()
     normals.SetInputData(model)
     normals.Update()
     normalspoint = normals.GetOutput().GetPointData().GetArray("Normals")
     model.GetPointData().SetNormals(normalspoint)
    def MinimumDistanceMask(self, vtkAlgorythmObject, distanceFromMask, ROI, ruler, isBubble=False):
        """ Takes an algorythm object which is will send through a pipeline to 
    create a mask defining the minimum distance value from the skin surface
    returns an algorythm object as well to preform GetOutput() -> polydata
    or GetOutputPort() -> algorythm
    see MinimumDistanceMask.pdf 
    """
        if distanceFromMask < 2:
            print "WARNING: MouldLogic: MinimumDistanceMask implicit",
            "modeling is very unstable below 1.5 , mask may degrade",
            "and lines will become discontinuous."
        Extents = self.utility.GetROIExtents(ROI)
        if isBubble:
            Extents = self.utility.ExpandExtents(Extents, 100)
        implicitModeller = vtk.vtkImplicitModeller()
        implicitModeller.SetInputConnection(vtkAlgorythmObject.GetOutputPort())
        implicitModeller.SetMaximumDistance(distanceFromMask)
        implicitModeller.SetModelBounds(Extents)
        implicitModeller.AdjustBoundsOn()
        implicitModeller.SetAdjustBounds(10)  # Removes the boundary effects
        implicitModeller.CappingOff()  # Important to create disjoint inner and outer masks
        implicitModeller.SetProcessModeToPerVoxel()
        implicitModeller.Update()

        contourFilter = vtk.vtkContourFilter()
        contourFilter.SetValue(0, distanceFromMask)
        contourFilter.SetInputConnection(implicitModeller.GetOutputPort())
        contourFilter.Update()

        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.FlipNormalsOn()
        normalsFunction.AddInputConnection(contourFilter.GetOutputPort())
        normalsFunction.Update()

        implicitBoxRegion = vtk.vtkBox()
        implicitBoxRegion.SetBounds(Extents)
        clipper2 = vtk.vtkClipPolyData()
        clipper2.InsideOutOn()  # Clip the regions outside of implicit function
        clipper2.SetInputConnection(normalsFunction.GetOutputPort())
        clipper2.SetClipFunction(implicitBoxRegion)
        clipper2.Update()

        closestPoint = [0, 0, 0]
        ruler.GetPosition1(closestPoint)
        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInputConnection(clipper2.GetOutputPort())
        connectivityFilter.SetExtractionModeToClosestPointRegion()
        connectivityFilter.SetClosestPoint(closestPoint)
        connectivityFilter.Update()

        return connectivityFilter.GetOutput()
    def marchingCubes( self, image, ijkToRasMatrix, threshold ):


        transformIJKtoRAS = vtk.vtkTransform()
        transformIJKtoRAS.SetMatrix( ijkToRasMatrix )

        marchingCubes = vtk.vtkMarchingCubes()
        marchingCubes.SetInput( image )
        marchingCubes.SetValue( 0, threshold )
        marchingCubes.ComputeScalarsOn()
        marchingCubes.ComputeGradientsOn()
        marchingCubes.ComputeNormalsOn()
        marchingCubes.GetOutput().ReleaseDataFlagOn()
        marchingCubes.Update()


        if transformIJKtoRAS.GetMatrix().Determinant() < 0:
            reverser = vtk.vtkReverseSense()
            reverser.SetInput( marchingCubes.GetOutput() )
            reverser.ReverseNormalsOn()
            reverser.GetOutput().ReleaseDataFlagOn()
            reverser.Update()
            correctedOutput = reverser.GetOutput()
        else:
            correctedOutput = marchingCubes.GetOutput()

        transformer = vtk.vtkTransformPolyDataFilter()
        transformer.SetInput( correctedOutput )
        transformer.SetTransform( transformIJKtoRAS )
        transformer.GetOutput().ReleaseDataFlagOn()
        transformer.Update()

        normals = vtk.vtkPolyDataNormals()
        normals.ComputePointNormalsOn()
        normals.SetInput( transformer.GetOutput() )
        normals.SetFeatureAngle( 60 )
        normals.SetSplitting( 1 )
        normals.GetOutput().ReleaseDataFlagOn()
        normals.Update()

        stripper = vtk.vtkStripper()
        stripper.SetInput( normals.GetOutput() )
        stripper.GetOutput().ReleaseDataFlagOff()
        stripper.Update()
        stripper.GetOutput().Update()

        result = vtk.vtkPolyData()
        result.DeepCopy( stripper.GetOutput() )
        result.Update()

        return result
Example #16
0
 def marchingCubes(self,image,ijkToRasMatrix,threshold):
     
     
     transformIJKtoRAS = vtk.vtkTransform()
     transformIJKtoRAS.SetMatrix(ijkToRasMatrix)
     
     marchingCubes = vtk.vtkMarchingCubes()
     marchingCubes.SetInput(image)
     marchingCubes.SetValue(0,threshold)
     marchingCubes.ComputeScalarsOn()
     marchingCubes.ComputeGradientsOn()
     marchingCubes.ComputeNormalsOn()
     marchingCubes.GetOutput().ReleaseDataFlagOn()
     marchingCubes.Update()
     
     
     if transformIJKtoRAS.GetMatrix().Determinant() < 0:
         reverser = vtk.vtkReverseSense()
         reverser.SetInput(marchingCubes.GetOutput())
         reverser.ReverseNormalsOn()
         reverser.GetOutput().ReleaseDataFlagOn()
         reverser.Update()
         correctedOutput = reverser.GetOutput()
     else:
         correctedOutput = marchingCubes.GetOutput()
     
     transformer = vtk.vtkTransformPolyDataFilter()
     transformer.SetInput(correctedOutput)
     transformer.SetTransform(transformIJKtoRAS)
     transformer.GetOutput().ReleaseDataFlagOn()
     transformer.Update()
     
     normals = vtk.vtkPolyDataNormals()
     normals.ComputePointNormalsOn()
     normals.SetInput(transformer.GetOutput())
     normals.SetFeatureAngle(60)
     normals.SetSplitting(1)
     normals.GetOutput().ReleaseDataFlagOn()
     normals.Update()
     
     stripper = vtk.vtkStripper()
     stripper.SetInput(normals.GetOutput())
     stripper.GetOutput().ReleaseDataFlagOff()
     stripper.Update()
     stripper.GetOutput().Update()
     
     result = vtk.vtkPolyData()
     result.DeepCopy(stripper.GetOutput())
     result.Update()
     
     return result
Example #17
0
    def CreateSegmentation(self, masterVolumeNode, outputObj):
        # Create segmentation
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            masterVolumeNode)
        addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(
            "segmentation")

        # Create segment editor to get access to effects
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

        # Thresholding
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", "1")
        effect.setParameter("MaximumThreshold", "999")
        effect.self().onApply()

        # Clean up
        segmentEditorWidget = None
        slicer.mrmlScene.RemoveNode(segmentEditorNode)

        # Make segmentation results visible in 3D
        segmentationNode.CreateClosedSurfaceRepresentation()

        # Make sure surface mesh cells are consistently oriented
        surfaceMesh = segmentationNode.GetClosedSurfaceRepresentation(
            addedSegmentID)
        normals = vtk.vtkPolyDataNormals()
        normals.AutoOrientNormalsOn()
        normals.ConsistencyOn()
        normals.SetInputData(surfaceMesh)
        normals.Update()
        surfaceMesh = normals.GetOutput()

        # Write to OBJ file
        writer = vtk.vtkOBJWriter()
        writer.SetInputData(surfaceMesh)
        writer.SetFileName(outputObj)
        writer.Update()
    def AddTubeToMask(self, maskPolydata, tube, ROI, radius, ruler):
        ROIExtents = self.utility.GetROIExtents(ROI)
        implicitFilter = vtk.vtkImplicitModeller()
        implicitFilter.SetInput(tube)
        implicitFilter.SetSampleDimensions(70, 70, 70)
        implicitFilter.SetMaximumDistance(radius)
        implicitFilter.SetModelBounds(ROIExtents)
        implicitFilter.SetProcessModeToPerVoxel()
        contourFilter = vtk.vtkContourFilter()
        contourFilter.SetValue(0, radius)
        implicitFilter.AdjustBoundsOn()
        implicitFilter.SetAdjustBounds(1)  # Removes the boundary effects
        implicitFilter.CappingOff()
        contourFilter.SetInputConnection(implicitFilter.GetOutputPort())
        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.AutoOrientNormalsOn()
        normalsFunction.AddInputConnection(contourFilter.GetOutputPort())

        unionFilter = vtk.vtkBooleanOperationPolyDataFilter()
        unionFilter.SetOperationToUnion()
        unionFilter.SetInput(0, normalsFunction.GetOutput())
        unionFilter.SetInput(1, maskPolydata)
        return unionFilter.GetOutput()
Example #19
0
    def AddTubeToMask(self, maskPolydata, tube, ROI, radius, ruler):
        ROIExtents = self.utility.GetROIExtents(ROI)
        implicitFilter = vtk.vtkImplicitModeller()
        implicitFilter.SetInput(tube)
        implicitFilter.SetSampleDimensions(70, 70, 70)
        implicitFilter.SetMaximumDistance(radius)
        implicitFilter.SetModelBounds(ROIExtents)
        implicitFilter.SetProcessModeToPerVoxel()
        contourFilter = vtk.vtkContourFilter()
        contourFilter.SetValue(0, radius)
        implicitFilter.AdjustBoundsOn()
        implicitFilter.SetAdjustBounds(1)  # Removes the boundary effects
        implicitFilter.CappingOff()
        contourFilter.SetInputConnection(implicitFilter.GetOutputPort())
        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.AutoOrientNormalsOn()
        normalsFunction.AddInputConnection(contourFilter.GetOutputPort())

        unionFilter = vtk.vtkBooleanOperationPolyDataFilter()
        unionFilter.SetOperationToUnion()
        unionFilter.SetInput(0, normalsFunction.GetOutput())
        unionFilter.SetInput(1, maskPolydata)
        return unionFilter.GetOutput()
Example #20
0
    def GenerateMould(self, facePolydata, distanceFromMask, ROI, tubePolydata,
                      clippedFace):
        ROIExtents = self.utility.GetROIExtents(ROI)
        outerFaceImplicitFunction = vtk.vtkImplicitModeller()
        outerFaceImplicitFunction.SetInputConnection(
            facePolydata.GetOutputPort())
        outerFaceImplicitFunction.SetSampleDimensions(70, 70, 70)
        outerFaceImplicitFunction.SetMaximumDistance(distanceFromMask)
        outerFaceImplicitFunction.SetModelBounds(ROIExtents)
        outerFaceImplicitFunction.SetProcessModeToPerVoxel()
        outerMaskContourFunction = vtk.vtkContourFilter()
        #TODO Find out the the allowed thinkness of the plastic
        THICKNESS = 3
        outerMaskContourFunction.SetValue(0, THICKNESS)
        outerMaskContourFunction.SetInputConnection(
            outerFaceImplicitFunction.GetOutputPort())

        outerFaceNormalsFunction = vtk.vtkPolyDataNormals()
        outerFaceNormalsFunction.AutoOrientNormalsOn()
        outerFaceNormalsFunction.AddInputConnection(
            outerMaskContourFunction.GetOutputPort())
        # Subtract the Tubes from the mask
        subtractionFilter1 = vtk.vtkBooleanOperationPolyDataFilter()
        subtractionFilter1.SetOperationToDifference()
        subtractionFilter1.SetInputConnection(
            0, outerFaceNormalsFunction.GetOutputPort())
        subtractionFilter1.SetInputConnection(1, tubePolydata.GetOutputPort())
        # Subtract the inner face from the outer face to make the mask
        subtractionFilter2 = vtk.vtkBooleanOperationPolyDataFilter()
        subtractionFilter2.SetOperationToDifference()
        subtractionFilter2.SetInputConnection(
            0, subtractionFilter1.GetOutputPort())
        subtractionFilter2.SetInputConnection(1, clippedFace.GetOutputPort())
        x = self.utility.DisplayPolyData("Mask",
                                         subtractionFilter2.GetOutput())
        x.SetColor(0.8, 0.8, 0.8)
        x.SetOpacity(1)
    def load(self, properties):
        try:
            filePath = properties["fileName"]
            tempDirectory = slicer.util.tempDirectory()

            if not slicer.util.extractArchive(filePath, tempDirectory):
                raise ValueError("Failed to extract file: " + filePath)

            # Parse header
            properties = {}
            timestamps = []
            headerSuffix = "_header.txt"
            for root, dirs, filenames in os.walk(tempDirectory):
                for filename in filenames:
                    if filename.endswith(headerSuffix):
                        # found header
                        print(filename)
                        internalBaseName = filename[:-len(headerSuffix)]
                        properties, timestamps = self.parseHeader(
                            os.path.join(root, filename))
                        break
            if not properties:
                raise ValueError(
                    "Failed to read file as TomTec UCD data file: " + filePath)

            # Get node base name from filename
            baseName = os.path.basename(filePath)
            suffix = ".UCD.data.zip"
            if baseName.endswith(suffix):
                baseName = baseName[:-len(suffix)]
            baseName = slicer.mrmlScene.GenerateUniqueName(baseName)

            sequenceNode = slicer.mrmlScene.AddNewNodeByClass(
                "vtkMRMLSequenceNode", baseName)
            sequenceNode.SetIndexName("time")
            sequenceNode.SetIndexUnit("ms")
            sequenceNode.SetIndexType(slicer.vtkMRMLSequenceNode.NumericIndex)
            for propertyName in [
                    "Average RR Duration", "Enddiastole time",
                    "Endsystole time"
            ]:
                sequenceNode.SetAttribute(propertyName,
                                          properties[propertyName][0])

            numberOfFrames = int(properties["Number of frames"][0])
            tempModelNode = slicer.mrmlScene.AddNewNodeByClass(
                "vtkMRMLModelNode", baseName + " temp")
            for frameIndex in range(numberOfFrames):
                # Read mesh
                meshFilePath = os.path.join(
                    tempDirectory,
                    "{0}_{1:02}.ucd".format(internalBaseName, frameIndex))
                reader = vtk.vtkAVSucdReader()
                reader.SetFileName(meshFilePath)
                reader.Update()
                # TomTec UCD files store surface mesh in unstructured grid - convert it to polydata
                extractSurface = vtk.vtkGeometryFilter()
                extractSurface.SetInputConnection(reader.GetOutputPort())
                normals = vtk.vtkPolyDataNormals()
                normals.SetInputConnection(extractSurface.GetOutputPort())
                normals.Update()
                # Save in sequence node
                tempModelNode.SetAndObserveMesh(normals.GetOutput())
                addedNode = sequenceNode.SetDataNodeAtValue(
                    tempModelNode, timestamps[frameIndex])

            import shutil
            shutil.rmtree(tempDirectory, True)

            slicer.mrmlScene.RemoveNode(tempModelNode)
            sequenceBrowserNode = slicer.mrmlScene.AddNewNodeByClass(
                "vtkMRMLSequenceBrowserNode", baseName + " browser")
            sequenceBrowserNode.SetAndObserveMasterSequenceNodeID(
                sequenceNode.GetID())

            # Disable scalar visibility by default (there is not really anything useful to show)
            proxyModelNode = sequenceBrowserNode.GetProxyNode(sequenceNode)
            proxyModelNode.GetDisplayNode().SetScalarVisibility(False)

            # Show sequence browser toolbar if a sequence has been loaded
            slicer.modules.sequences.showSequenceBrowser(sequenceBrowserNode)

        except Exception as e:
            logging.error("Failed to load TomTec UCD data file: " + str(e))
            import traceback
            traceback.print_exc()
            return False
        return True
Example #22
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
Example #24
0
    def PolyDataToImageData(self,
                            inputPolydata_Ras,
                            referenceVolumeNode_Ras,
                            inVal=100,
                            outVal=0):
        """ We take in an polydata and convert it to an new image data , withing the Reference Voulume node
        the reference volume node is cleared with a threshold because originally the volume may contain
        alot of noisy pixels 
        PARAM: inputPolydata_Ras: Polydata we are looking to conver       vtkPolydata()
        PARAM: refernceVolumeNode_Ras                                     vtkMRMLScalarVolumeNode()
        RETURN : vtkImageData
        """
        """ Transform the polydata from ras to ijk using the referenceVolumeNode """
        #inputPolydataTriangulated_Ijk=polyToImage.GetOutput()
        transformPolydataFilter = vtk.vtkTransformPolyDataFilter()
        rasToIjkMatrix = vtk.vtkMatrix4x4()
        referenceVolumeNode_Ras.GetRASToIJKMatrix(rasToIjkMatrix)
        rasToIjkTransform = vtk.vtkTransform()
        rasToIjkTransform.SetMatrix(rasToIjkMatrix)
        transformPolydataFilter.SetTransform(rasToIjkTransform)
        transformPolydataFilter.SetInputData(inputPolydata_Ras)
        transformPolydataFilter.Update()
        inputPolydata_Ijk = transformPolydataFilter.GetOutput()
        normalsFunction = vtk.vtkPolyDataNormals()
        normalsFunction.SetInputData(inputPolydata_Ijk)
        normalsFunction.ConsistencyOn()
        trigFilter = vtk.vtkTriangleFilter()
        trigFilter.SetInputConnection(normalsFunction.GetOutputPort())
        stripper = vtk.vtkStripper()
        stripper.SetInputConnection(trigFilter.GetOutputPort())
        stripper.Update()
        inputPolydataTriangulated_Ijk = stripper.GetOutput()

        # Clone reference image and clear it
        referenceImage_Ijk = referenceVolumeNode_Ras.GetImageData()

        # Fill image with outVal (there is no volume Fill filter in VTK, therefore we need to use threshold filter)
        thresh = vtk.vtkImageThreshold()
        thresh.ReplaceInOn()
        thresh.ReplaceOutOn()
        thresh.SetInValue(outVal)
        thresh.SetOutValue(outVal)
        #thresh.SetOutputScalarType (vtk.VTK_UNSIGNED_CHAR)
        thresh.SetInputData(referenceImage_Ijk)
        thresh.Update()
        whiteImage_Ijk = thresh.GetOutput()

        # Convert polydata to stencil
        polyToImage = vtk.vtkPolyDataToImageStencil()
        polyToImage.SetInputData(inputPolydataTriangulated_Ijk)
        polyToImage.SetOutputSpacing(whiteImage_Ijk.GetSpacing())
        polyToImage.SetOutputOrigin(whiteImage_Ijk.GetOrigin())
        polyToImage.SetOutputWholeExtent(whiteImage_Ijk.GetExtent())
        polyToImage.Update()
        imageStencil_Ijk = polyToImage.GetOutput()

        # Convert stencil to image
        imgstenc = vtk.vtkImageStencil()
        imgstenc.SetInputData(whiteImage_Ijk)
        imgstenc.SetStencilData(imageStencil_Ijk)
        imgstenc.ReverseStencilOn()
        imgstenc.SetBackgroundValue(inVal)
        imgstenc.Update()
        return imgstenc.GetOutput()
Example #25
0
  def PolyDataToImageData(self, inputPolydata_Ras, referenceVolumeNode_Ras, inVal=100, outVal=0):
    """ We take in an polydata and convert it to an new image data , withing the Reference Voulume node
        the reference volume node is cleared with a threshold because originally the volume may contain
        alot of noisy pixels 
        PARAM: inputPolydata_Ras: Polydata we are looking to conver       vtkPolydata()
        PARAM: refernceVolumeNode_Ras                                     vtkMRMLScalarVolumeNode()
        RETURN : vtkImageData
        """
    
    """ Transform the polydata from ras to ijk using the referenceVolumeNode """
    #inputPolydataTriangulated_Ijk=polyToImage.GetOutput()
    transformPolydataFilter=vtk.vtkTransformPolyDataFilter()
    rasToIjkMatrix=vtk.vtkMatrix4x4()
    referenceVolumeNode_Ras.GetRASToIJKMatrix(rasToIjkMatrix)
    rasToIjkTransform = vtk.vtkTransform()
    rasToIjkTransform.SetMatrix(rasToIjkMatrix)
    transformPolydataFilter.SetTransform(rasToIjkTransform)
    transformPolydataFilter.SetInputData(inputPolydata_Ras)
    transformPolydataFilter.Update()
    inputPolydata_Ijk=transformPolydataFilter.GetOutput()
    normalsFunction=vtk.vtkPolyDataNormals()
    normalsFunction.SetInputData(inputPolydata_Ijk)
    normalsFunction.ConsistencyOn()
    trigFilter=vtk.vtkTriangleFilter()
    trigFilter.SetInputConnection(normalsFunction.GetOutputPort())
    stripper=vtk.vtkStripper()
    stripper.SetInputConnection(trigFilter.GetOutputPort())
    stripper.Update()
    inputPolydataTriangulated_Ijk=stripper.GetOutput()
    
    # Clone reference image and clear it
    referenceImage_Ijk = referenceVolumeNode_Ras.GetImageData()
    
    # Fill image with outVal (there is no volume Fill filter in VTK, therefore we need to use threshold filter)
    thresh = vtk.vtkImageThreshold()
    thresh.ReplaceInOn()
    thresh.ReplaceOutOn()
    thresh.SetInValue(outVal)
    thresh.SetOutValue(outVal)
    #thresh.SetOutputScalarType (vtk.VTK_UNSIGNED_CHAR)
    thresh.SetInputData(referenceImage_Ijk)
    thresh.Update()
    whiteImage_Ijk = thresh.GetOutput()

    # Convert polydata to stencil
    polyToImage = vtk.vtkPolyDataToImageStencil()
    polyToImage.SetInputData(inputPolydataTriangulated_Ijk)
    polyToImage.SetOutputSpacing(whiteImage_Ijk.GetSpacing())
    polyToImage.SetOutputOrigin(whiteImage_Ijk.GetOrigin())
    polyToImage.SetOutputWholeExtent(whiteImage_Ijk.GetExtent())
    polyToImage.Update()
    imageStencil_Ijk=polyToImage.GetOutput()
    
    # Convert stencil to image
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(whiteImage_Ijk)
    imgstenc.SetStencilData(imageStencil_Ijk)
    imgstenc.ReverseStencilOn()
    imgstenc.SetBackgroundValue(inVal)
    imgstenc.Update()
    return imgstenc.GetOutput()