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 planeModel(self, scene, normal, origin, name, color): """ Create a plane model node which can be viewed in the 3D View """ #A plane source plane = vtk.vtkPlane() plane.SetOrigin(origin) plane.SetNormal(normal) planeSample = vtk.vtkSampleFunction() planeSample.SetImplicitFunction(plane) planeSample.SetModelBounds(-100,100,-100,100,-100,100) planeSample.SetSampleDimensions(100,100,100) planeSample.ComputeNormalsOff() planeContour = vtk.vtkContourFilter() planeContour.SetInput(planeSample.GetOutput()) # Create plane model node planeNode = slicer.vtkMRMLModelNode() planeNode.SetScene(scene) planeNode.SetName(name) planeNode.SetAndObservePolyData(planeContour.GetOutput()) # Create plane display model node planeModelDisplay = slicer.vtkMRMLModelDisplayNode() planeModelDisplay.SetColor(color) planeModelDisplay.SetBackfaceCulling(0) planeModelDisplay.SetScene(scene) scene.AddNode(planeModelDisplay) planeNode.SetAndObserveDisplayNodeID(planeModelDisplay.GetID()) #Add to scene planeModelDisplay.SetInputPolyData(planeContour.GetOutput()) scene.AddNode(planeNode) return plane
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 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 PointsToSurfacePolyData( self, inPoints, reverse ): # Create a polydata object from the points pointsPolyData = vtk.vtkPolyData() pointsPolyData.SetPoints( inPoints ) # Create the surface filter from the polydata surfaceFilter = vtk.vtkSurfaceReconstructionFilter() surfaceFilter.SetInputData( pointsPolyData ) surfaceFilter.Update() # Do the contouring filter, and reverse to ensure it works properly contourFilter = vtk.vtkContourFilter() contourFilter.SetValue( 0, 0.0 ) contourFilter.SetInputData( surfaceFilter.GetOutput() ) contourFilter.Update() # Reverse the normals if necessary reverseFilter = vtk.vtkReverseSense() reverseFilter.SetInputData( contourFilter.GetOutput() ) reverseFilter.SetReverseCells( reverse ) reverseFilter.SetReverseNormals( reverse ) reverseFilter.Update() # Reset the scaling to let the surface match the points fiducialBounds = [ 0, 0, 0, 0, 0, 0 ] pointsPolyData.GetBounds( fiducialBounds ) tissueBounds = [ 0, 0, 0, 0, 0, 0 ] reverseFilter.GetOutput().GetBounds( tissueBounds ) scaleX = ( fiducialBounds[1] - fiducialBounds[0] ) / ( tissueBounds[1] - tissueBounds[0] ) scaleY = ( fiducialBounds[3] - fiducialBounds[2] ) / ( tissueBounds[3] - tissueBounds[2] ) scaleZ = ( fiducialBounds[5] - fiducialBounds[4] ) / ( tissueBounds[5] - tissueBounds[4] ) transform = vtk.vtkTransform() transform.Translate( fiducialBounds[0], fiducialBounds[2], fiducialBounds[4] ) transform.Scale( scaleX, scaleY, scaleZ ) transform.Translate( - tissueBounds[0], - tissueBounds[2], - tissueBounds[4] ) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputData( reverseFilter.GetOutput() ) transformFilter.SetTransform( transform ) transformFilter.Update() return transformFilter.GetOutput()
def CreateBackLine(self, ruler, ROI, implicitPlane): """ Creates the polydata for where the cutting plane hits the the back of the ROI. This backline will be used to close the catheter path allowing for the specification of Towards or Away from the face ASSERTION: that the ruler's second point will be closest to the front of our mask. """ roiPoints = self.utility.GetROIPoints(ROI) frontExtentIndex = self.utility.GetClosestExtent(ruler, ROI) backExtentIndex = self.utility.GetOppositeExtent(frontExtentIndex) #Creating an implict plane for the back of the ROI ROICenterPoint = [0, 0, 0] ROI.GetXYZ(ROICenterPoint) backNormal = self.utility.GetVector(ROICenterPoint, roiPoints[backExtentIndex]) backPlane = vtk.vtkPlane() backPlane.SetNormal(backNormal) backPlane.SetOrigin(roiPoints[backExtentIndex]) #Finding the Intercept of this and the CuttingPlane sampleFunction = vtk.vtkSampleFunction() sampleFunction.SetSampleDimensions(10, 10, 10) sampleFunction.SetImplicitFunction(backPlane) bounds = self.utility.ExpandExtents(self.utility.GetROIExtents(ROI), 1) sampleFunction.SetModelBounds(bounds) sampleFunction.Update() contourFilter = vtk.vtkContourFilter() contourFilter.SetInputConnection(sampleFunction.GetOutputPort()) contourFilter.GenerateValues(1, 1, 1) contourFilter.Update() cutter = vtk.vtkCutter() cutter.SetInputConnection(contourFilter.GetOutputPort()) cutter.SetCutFunction(implicitPlane) cutter.GenerateValues(1, 1, 1) cutter.Update() self.listOfBackLines.append(cutter.GetOutput()) PATH = self.ROOTPATH + "\\doc\\DebugPolyData\\" + "BackLine-" + str( len(self.listOfBackLines)) self.utility.PolyDataWriter(self.listOfBackLines[-1], PATH + ".vtk")
def CreateBackLine(self, ruler, ROI, implicitPlane): """ Creates the polydata for where the cutting plane hits the the back of the ROI. This backline will be used to close the catheter path allowing for the specification of Towards or Away from the face ASSERTION: that the ruler's second point will be closest to the front of our mask. """ roiPoints = self.utility.GetROIPoints(ROI) frontExtentIndex = self.utility.GetClosestExtent(ruler, ROI) backExtentIndex = self.utility.GetOppositeExtent(frontExtentIndex) # Creating an implict plane for the back of the ROI ROICenterPoint = [0, 0, 0] ROI.GetXYZ(ROICenterPoint) backNormal = self.utility.GetVector(ROICenterPoint, roiPoints[backExtentIndex]) backPlane = vtk.vtkPlane() backPlane.SetNormal(backNormal) backPlane.SetOrigin(roiPoints[backExtentIndex]) # Finding the Intercept of this and the CuttingPlane sampleFunction = vtk.vtkSampleFunction() sampleFunction.SetSampleDimensions(10, 10, 10) sampleFunction.SetImplicitFunction(backPlane) bounds = self.utility.ExpandExtents(self.utility.GetROIExtents(ROI), 1) sampleFunction.SetModelBounds(bounds) sampleFunction.Update() contourFilter = vtk.vtkContourFilter() contourFilter.SetInputConnection(sampleFunction.GetOutputPort()) contourFilter.GenerateValues(1, 1, 1) contourFilter.Update() cutter = vtk.vtkCutter() cutter.SetInputConnection(contourFilter.GetOutputPort()) cutter.SetCutFunction(implicitPlane) cutter.GenerateValues(1, 1, 1) cutter.Update() self.listOfBackLines.append(cutter.GetOutput()) PATH = self.ROOTPATH + "\\doc\\DebugPolyData\\" + "BackLine-" + str(len(self.listOfBackLines)) self.utility.PolyDataWriter(self.listOfBackLines[-1], PATH + ".vtk")
def DisplayImplicit(self,name,implicitFunction, ROI=None, Extents=None): """This function takes an implicitFunction and displays it within the ROI It will return the modelDisplaynode assosiated with in so that attributes can be changed """ sampleFunction=vtk.vtkSampleFunction() sampleFunction.SetSampleDimensions(70,70,70) sampleFunction.SetImplicitFunction(implicitFunction) ROIExtents=[0,0,0,0,0,0] if ROI==None: ROIExtents=Extents else: ROIExtents=self.GetROIExtents(ROI) sampleFunction.SetModelBounds(ROIExtents) sampleFunction.Update() contourFilter=vtk.vtkContourFilter() contourFilter.SetInputConnection(sampleFunction.GetOutputPort()) contourFilter.GenerateValues(1,0,0) contourFilter.Update() polyData=contourFilter.GetOutput() modelDisplayNode=self.DisplayPolyData(name,polyData) return modelDisplayNode
def DisplayImplicit(self, name, implicitFunction, ROI=None, Extents=None): """This function takes an implicitFunction and displays it within the ROI It will return the modelDisplaynode assosiated with in so that attributes can be changed """ sampleFunction = vtk.vtkSampleFunction() sampleFunction.SetSampleDimensions(70, 70, 70) sampleFunction.SetImplicitFunction(implicitFunction) ROIExtents = [0, 0, 0, 0, 0, 0] if ROI == None: ROIExtents = Extents else: ROIExtents = self.GetROIExtents(ROI) sampleFunction.SetModelBounds(ROIExtents) sampleFunction.Update() contourFilter = vtk.vtkContourFilter() contourFilter.SetInputConnection(sampleFunction.GetOutputPort()) contourFilter.GenerateValues(1, 0, 0) contourFilter.Update() polyData = contourFilter.GetOutput() modelDisplayNode = self.DisplayPolyData(name, polyData) return modelDisplayNode
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()
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 updateModelFromMarkup(self, inputMarkup, outputModel): """ Update model to enclose all points in the input markup list """ # Delaunay triangulation is robust and creates nice smooth surfaces from a small number of points, # however it can only generate convex surfaces robustly. useDelaunay = True # Create polydata point set from markup points points = vtk.vtkPoints() cellArray = vtk.vtkCellArray() numberOfPoints = inputMarkup.GetNumberOfFiducials() # Surface generation algorithms behave unpredictably when there are not enough points # return if there are very few points if useDelaunay: if numberOfPoints < 3: return else: if numberOfPoints < 10: return points.SetNumberOfPoints(numberOfPoints) new_coord = [0.0, 0.0, 0.0] for i in range(numberOfPoints): inputMarkup.GetNthFiducialPosition(i, new_coord) points.SetPoint(i, new_coord) cellArray.InsertNextCell(numberOfPoints) for i in range(numberOfPoints): cellArray.InsertCellPoint(i) pointPolyData = vtk.vtkPolyData() pointPolyData.SetLines(cellArray) pointPolyData.SetPoints(points) # Create surface from point set if useDelaunay: delaunay = vtk.vtkDelaunay3D() delaunay.SetInputData(pointPolyData) surfaceFilter = vtk.vtkDataSetSurfaceFilter() surfaceFilter.SetInputConnection(delaunay.GetOutputPort()) smoother = vtk.vtkButterflySubdivisionFilter() smoother.SetInputConnection(surfaceFilter.GetOutputPort()) smoother.SetNumberOfSubdivisions(3) smoother.Update() outputModel.SetPolyDataConnection(smoother.GetOutputPort()) else: surf = vtk.vtkSurfaceReconstructionFilter() surf.SetInputData(pointPolyData) surf.SetNeighborhoodSize(20) surf.SetSampleSpacing( 80 ) # lower value follows the small details more closely but more dense pointset is needed as input cf = vtk.vtkContourFilter() cf.SetInputConnection(surf.GetOutputPort()) cf.SetValue(0, 0.0) # Sometimes the contouring algorithm can create a volume whose gradient # vector and ordering of polygon (using the right hand rule) are # inconsistent. vtkReverseSense cures this problem. reverse = vtk.vtkReverseSense() reverse.SetInputConnection(cf.GetOutputPort()) reverse.ReverseCellsOff() reverse.ReverseNormalsOff() outputModel.SetPolyDataConnection(reverse.GetOutputPort()) # Create default model display node if does not exist yet if not outputModel.GetDisplayNode(): modelDisplayNode = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLModelDisplayNode") modelDisplayNode.SetColor(0, 0, 1) # Blue modelDisplayNode.BackfaceCullingOff() modelDisplayNode.SliceIntersectionVisibilityOn() modelDisplayNode.SetOpacity(0.3) # Between 0-1, 1 being opaque slicer.mrmlScene.AddNode(modelDisplayNode) outputModel.SetAndObserveDisplayNodeID(modelDisplayNode.GetID()) outputModel.GetDisplayNode().SliceIntersectionVisibilityOn() outputModel.Modified()
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