def openSurfaceAtPoint(self, polyData, seed): ''' Returns a new surface with an opening at the given seed. ''' someradius = 1.0 pointLocator = vtk.vtkPointLocator() pointLocator.SetDataSet(polyData) pointLocator.BuildLocator() # find the closest point next to the seed on the surface #id = pointLocator.FindClosestPoint(int(seed[0]),int(seed[1]),int(seed[2])) id = pointLocator.FindClosestPoint(seed) # the seed is now guaranteed on the surface seed = polyData.GetPoint(id) sphere = vtk.vtkSphere() sphere.SetCenter(seed[0], seed[1], seed[2]) sphere.SetRadius(someradius) clip = vtk.vtkClipPolyData() clip.SetInput(polyData) clip.SetClipFunction(sphere) clip.Update() outPolyData = vtk.vtkPolyData() outPolyData.DeepCopy(clip.GetOutput()) outPolyData.Update() return outPolyData
def openSurfaceAtPoint( self, polyData, seed ): ''' Returns a new surface with an opening at the given seed. ''' someradius = 1.0 pointLocator = vtk.vtkPointLocator() pointLocator.SetDataSet( polyData ) pointLocator.BuildLocator() # find the closest point next to the seed on the surface # id = pointLocator.FindClosestPoint(int(seed[0]),int(seed[1]),int(seed[2])) id = pointLocator.FindClosestPoint( seed ) # the seed is now guaranteed on the surface seed = polyData.GetPoint( id ) sphere = vtk.vtkSphere() sphere.SetCenter( seed[0], seed[1], seed[2] ) sphere.SetRadius( someradius ) clip = vtk.vtkClipPolyData() clip.SetInputData( polyData ) clip.SetClipFunction( sphere ) clip.Update() outPolyData = vtk.vtkPolyData() outPolyData.DeepCopy( clip.GetOutput() ) return outPolyData
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 createSyntheticMask(self, maskVolumeNode, radius): """ Run the actual algorithm """ roiSphere = vtk.vtkSphere() roiCenter = [0, 0, 0] roiOrigin = [0, 0, 0] roiSpacing = [1, 1, 1] roiDimension = [100, 100, 100] # roiDimension = refVolumeNode.GetImageData().GetDimensions() roiCenter[0] = roiOrigin[0] + roiDimension[0] * roiSpacing[0] / 2 roiCenter[1] = roiOrigin[1] + roiDimension[1] * roiSpacing[1] / 2 roiCenter[2] = roiOrigin[2] + roiDimension[2] * roiSpacing[2] / 2 print "roiCenter", roiCenter """ ijkToRas = vtk.vtkMatrix4x4() refVolumeNode.GetIJKToRASMatrix( ijkToRas ) roiPoint = [0,0,0,1]; roiPoint[0] = roiCenter[0] roiPoint[1] = roiCenter[1] roiPoint[2] = roiCenter[2] roiPoint = ijkToRas.MultiplyPoint(roiPoint) roiCenter[0] = roiPoint[0] roiCenter[1] = roiPoint[1] roiCenter[2] = roiPoint[2] print "roiCenter", roiCenter """ roiSphere.SetCenter(roiCenter) roiSphere.SetRadius(radius) # Determine the transform between the box and the image IJK coordinate systems rasToSphere = vtk.vtkMatrix4x4() # if roiNode.GetTransformNodeID() != None: # roiSphereTransformNode = slicer.mrmlScene.GetNodeByID(roiNode.GetTransformNodeID()) # sphereToRas = vtk.vtkMatrix4x4() # roiSphereTransformNode.GetMatrixTransformToWorld(sphereToRas) # rasToSphere.DeepCopy(sphereToRas) # rasToSphere.Invert() """ ijkToSphere = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(rasToSphere,ijkToRas,ijkToSphere) ijkToSphereTransform = vtk.vtkTransform() ijkToSphereTransform.SetMatrix(ijkToSphere) roiSphere.SetTransform(ijkToSphereTransform) # Use the stencil to fill the volume refImageData = refVolumeNode.GetImageData() """ imageSource = vtk.vtkImageNoiseSource() imageSource.SetMinimum(0) imageSource.SetMaximum(0) imageSource.SetWholeExtent(0, roiDimension[0] - 1, 0, roiDimension[1] - 1, 0, roiDimension[2] - 1) imageSource.Update() imageCast = vtk.vtkImageCast() imageCast.SetInputData(imageSource.GetOutput()) imageCast.SetOutputScalarTypeToUnsignedChar() imageCast.Update() """ changeInfo = vtk.vtkImageChangeInformation() changeInfo.SetInputData(imageCast.GetOutput()) changeInfo.SetOutputOrigin(refImageData.GetOrigin()) changeInfo.SetOutputSpacing(refImageData.GetSpacing()) changeInfo.Update() """ # Convert the implicit function to a stencil functionToStencil = vtk.vtkImplicitFunctionToImageStencil() functionToStencil.SetInput(roiSphere) functionToStencil.SetOutputOrigin(0, 0, 0) functionToStencil.SetOutputSpacing(1, 1, 1) functionToStencil.SetOutputWholeExtent(0, roiDimension[0] - 1, 0, roiDimension[1] - 1, 0, roiDimension[2] - 1) functionToStencil.Update() # Apply the stencil to the volume stencilToImage = vtk.vtkImageStencil() stencilToImage.SetInputData(imageCast.GetOutput()) stencilToImage.SetStencilData(functionToStencil.GetOutput()) stencilToImage.ReverseStencilOn() stencilToImage.SetBackgroundValue(1) stencilToImage.Update() """ extent = refImageData.GetWholeExtent() resample = vtk.vtkImageReslice() resample.SetInputData(stencilToImage.GetOutput()) resample.SetOutputOrigin(refImageData.GetOrigin()) resample.SetOutputSpacing(refImageData.GetSpacing()[0]/2, refImageData.GetSpacing()[1]/2, refImageData.GetSpacing()[2]/2 ) resample.SetOutputExtent(extent[0], (extent[1]-extent[0])*2-1, extent[2], (extent[3]-extent[2])*2-1, extent[4], (extent[5]-extent[4])*2-1) resample.Update() changeInfo2 = vtk.vtkImageChangeInformation() changeInfo2.SetInputData(resample.GetOutput()) changeInfo2.SetOutputOrigin(refImageData.GetOrigin()) changeInfo2.SetOutputSpacing(refImageData.GetSpacing()) changeInfo2.Update() """ # Update the volume with the stencil operation result maskVolumeNode.SetAndObserveImageData(stencilToImage.GetOutput()) maskVolumeNode.SetOrigin(0, 0, 0) maskVolumeNode.SetSpacing(1, 1, 1) # maskVolumeNode.CopyOrientation(refVolumeNode) mgr = slicer.app.layoutManager() mgr.sliceWidget( 'Red').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( maskVolumeNode.GetID()) mgr.sliceWidget( 'Yellow').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( maskVolumeNode.GetID()) mgr.sliceWidget( 'Green').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( maskVolumeNode.GetID())
def iceCream(self): # based on iceCream.py from VTK/Examples/Modelling # This example demonstrates how to use boolean combinations of implicit # functions to create a model of an ice cream cone. import vtk from vtk.util.colors import chocolate, mint # Create implicit function primitives. These have been carefully # placed to give the effect that we want. We are going to use various # combinations of these functions to create the shape we want; for # example, we use planes intersected with a cone (which is infinite in # extent) to get a finite cone. cone = vtk.vtkCone() cone.SetAngle(20) vertPlane = vtk.vtkPlane() vertPlane.SetOrigin(.1, 0, 0) vertPlane.SetNormal(-1, 0, 0) basePlane = vtk.vtkPlane() basePlane.SetOrigin(1.2, 0, 0) basePlane.SetNormal(1, 0, 0) iceCream = vtk.vtkSphere() iceCream.SetCenter(1.333, 0, 0) iceCream.SetRadius(0.5) bite = vtk.vtkSphere() bite.SetCenter(1.5, 0, 0.5) bite.SetRadius(0.25) # Combine primitives to build ice-cream cone. Clip the cone with planes. theCone = vtk.vtkImplicitBoolean() theCone.SetOperationTypeToIntersection() theCone.AddFunction(cone) theCone.AddFunction(vertPlane) theCone.AddFunction(basePlane) # Take a bite out of the ice cream. theCream = vtk.vtkImplicitBoolean() theCream.SetOperationTypeToDifference() theCream.AddFunction(iceCream) theCream.AddFunction(bite) # The sample function generates a distance function from the implicit # function (which in this case is the cone). This is then contoured to # get a polygonal surface. theConeSample = vtk.vtkSampleFunction() theConeSample.SetImplicitFunction(theCone) theConeSample.SetModelBounds(-1, 1.5, -1.25, 1.25, -1.25, 1.25) theConeSample.SetSampleDimensions(60, 60, 60) theConeSample.ComputeNormalsOff() theConeSurface = vtk.vtkContourFilter() theConeSurface.SetInputConnection(theConeSample.GetOutputPort()) theConeSurface.SetValue(0, 0.0) coneMapper = vtk.vtkPolyDataMapper() coneMapper.SetInputConnection(theConeSurface.GetOutputPort()) coneMapper.ScalarVisibilityOff() coneActor = vtk.vtkActor() coneActor.SetMapper(coneMapper) coneActor.GetProperty().SetColor(chocolate) # The same here for the ice cream. theCreamSample = vtk.vtkSampleFunction() theCreamSample.SetImplicitFunction(theCream) theCreamSample.SetModelBounds(0, 2.5, -1.25, 1.25, -1.25, 1.25) theCreamSample.SetSampleDimensions(60, 60, 60) theCreamSample.ComputeNormalsOff() theCreamSurface = vtk.vtkContourFilter() theCreamSurface.SetInputConnection(theCreamSample.GetOutputPort()) theCreamSurface.SetValue(0, 0.0) creamMapper = vtk.vtkPolyDataMapper() creamMapper.SetInputConnection(theCreamSurface.GetOutputPort()) creamMapper.ScalarVisibilityOff() creamActor = vtk.vtkActor() creamActor.SetMapper(creamMapper) creamActor.GetProperty().SetColor(mint) # Create the usual rendering stuff ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) # Add the actors to the renderer, set the background and size ren.AddActor(coneActor) ren.AddActor(creamActor) ren.SetBackground(1, 1, 1) renWin.SetSize(500, 500) ren.ResetCamera() ren.GetActiveCamera().Roll(90) ren.GetActiveCamera().Dolly(1.5) ren.ResetCameraClippingRange() iren.Initialize() renWin.Render() iren.Start() return iren
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