def setupMRMLTracking(self): if not hasattr(self, "trackingDevice"): """ set up the mrml parts or use existing """ nodes = slicer.mrmlScene.GetNodesByName('trackingDevice') if nodes.GetNumberOfItems() > 0: self.trackingDevice = nodes.GetItemAsObject(0) nodes = slicer.mrmlScene.GetNodesByName('tracker') self.tracker = nodes.GetItemAsObject(0) else: # trackingDevice cursor self.cube = vtk.vtkCubeSource() self.cube.SetXLength(30) self.cube.SetYLength(70) self.cube.SetZLength(5) self.cube.Update() # display node self.modelDisplay = slicer.vtkMRMLModelDisplayNode() self.modelDisplay.SetColor(1,1,0) # yellow slicer.mrmlScene.AddNode(self.modelDisplay) # self.modelDisplay.SetPolyData(self.cube.GetOutputPort()) # Create model node self.trackingDevice = slicer.vtkMRMLModelNode() self.trackingDevice.SetScene(slicer.mrmlScene) self.trackingDevice.SetName("trackingDevice") self.trackingDevice.SetAndObservePolyData(self.cube.GetOutputDataObject(0)) self.trackingDevice.SetAndObserveDisplayNodeID(self.modelDisplay.GetID()) slicer.mrmlScene.AddNode(self.trackingDevice) # tracker self.tracker = slicer.vtkMRMLLinearTransformNode() self.tracker.SetName('tracker') slicer.mrmlScene.AddNode(self.tracker) self.trackingDevice.SetAndObserveTransformNodeID(self.tracker.GetID())
def createBox(X, Y, Z, name): miterBox = slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelNode') miterBox.SetName(slicer.mrmlScene.GetUniqueNameByString(name)) slicer.mrmlScene.AddNode(miterBox) miterBox.CreateDefaultDisplayNodes() miterBoxSource = vtk.vtkCubeSource() miterBoxSource.SetXLength(X) miterBoxSource.SetYLength(Y) miterBoxSource.SetZLength(Z) triangleFilter = vtk.vtkTriangleFilter() triangleFilter.SetInputConnection(miterBoxSource.GetOutputPort()) #triangleFilter.Update() miterBox.SetPolyDataConnection(triangleFilter.GetOutputPort()) return miterBox
def cropPoints(self, input): #Get bounds of screw bounds = input.GetPolyData().GetBounds() #Create a cube with bounds equal to that of the screw minus the head (-17) cropCube = vtk.vtkCubeSource() cropCube.SetBounds(bounds[0],bounds[1],bounds[2],bounds[3]-17,bounds[4],bounds[5]) #Select points on screw within cube select = vtk.vtkSelectEnclosedPoints() select.SetInput(input.GetPolyData()) select.SetSurface(cropCube.GetOutput()) select.Update() return select
def startTransformMapping(self, groundTruthTransformNode, mappedTransformNode, outputVisitedPointsModelNode, positionErrorTransformNode, orientationErrorTransformNode): self.removeObservers() self.groundTruthTransformNode = groundTruthTransformNode self.mappedTransformNode = mappedTransformNode self.outputVisitedPointsModelNode = outputVisitedPointsModelNode self.positionErrorTransformNode = positionErrorTransformNode self.orientationErrorTransformNode = orientationErrorTransformNode self.positionErrorMagnitudeList = [] self.orientationErrorMagnitudeList = [] if self.outputVisitedPointsModelNode: if not self.outputVisitedPointsModelNode.GetDisplayNode(): modelDisplay = slicer.vtkMRMLModelDisplayNode() #modelDisplay.SetSliceIntersectionVisibility(False) # Show in slice view #modelDisplay.SetEdgeVisibility(True) # Hide in 3D view modelDisplay.SetEdgeVisibility(True) slicer.mrmlScene.AddNode(modelDisplay) self.outputVisitedPointsModelNode.SetAndObserveDisplayNodeID(modelDisplay.GetID()) self.visitedPoints = vtk.vtkPoints() self.visitedPointsPolydata = vtk.vtkPolyData() self.visitedPointsPolydata.SetPoints(self.visitedPoints) glyph = vtk.vtkPolyData() cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(self.minimumSamplingDistance) cubeSource.SetYLength(self.minimumSamplingDistance) cubeSource.SetZLength(self.minimumSamplingDistance) self.visitedPointsGlyph3d = vtk.vtkGlyph3D() self.visitedPointsGlyph3d.SetSourceConnection(cubeSource.GetOutputPort()) self.visitedPointsGlyph3d.SetInputData(self.visitedPointsPolydata) self.visitedPointsGlyph3d.Update() self.outputVisitedPointsModelNode.SetPolyDataConnection(self.visitedPointsGlyph3d.GetOutputPort()) self.initializeErrorTransform(self.positionErrorTransformNode) self.initializeErrorTransform(self.orientationErrorTransformNode) # Start the updates self.addObservers() self.onGroundTruthTransformNodeModified(0,0)
def tableCursor(self, dimensions=(900, 30, 600)): """Create the mrml structure to represent the table if needed otherwise return the current transform dimensions : left-right, up-down, in-out size of table """ transformName = 'Table-To-Camera' transformNode = slicer.util.getNode(transformName) if not transformNode: # make the mrml box = vtk.vtkCubeSource() box.SetXLength(dimensions[0]) box.SetYLength(dimensions[1]) box.SetZLength(dimensions[2]) box.SetCenter(0, -dimensions[1] / 2., 0) box.Update() # Create model node cursor = slicer.vtkMRMLModelNode() cursor.SetScene(slicer.mrmlScene) cursor.SetName("Cursor-Table") cursor.SetAndObservePolyData(box.GetOutput()) # Create display node cursorModelDisplay = slicer.vtkMRMLModelDisplayNode() cursorModelDisplay.SetColor( (0.86274509803921573, ) * 3) # 'gainsboro' cursorModelDisplay.SetOpacity(0.5) cursorModelDisplay.SetScene(slicer.mrmlScene) slicer.mrmlScene.AddNode(cursorModelDisplay) cursor.SetAndObserveDisplayNodeID(cursorModelDisplay.GetID()) # Add to slicer.mrmlScene cursorModelDisplay.SetInputPolyData(box.GetOutput()) slicer.mrmlScene.AddNode(cursor) # Create transform node transformNode = slicer.vtkMRMLLinearTransformNode() transformNode.SetName(transformName) slicer.mrmlScene.AddNode(transformNode) tableToCamera = vtk.vtkMatrix4x4() tableToCamera.SetElement(1, 3, -100) transformNode.GetMatrixTransformToParent().DeepCopy(tableToCamera) cursor.SetAndObserveTransformNodeID(transformNode.GetID()) return transformNode
def tableCursor(self,dimensions=(900,30,600)): """Create the mrml structure to represent the table if needed otherwise return the current transform dimensions : left-right, up-down, in-out size of table """ transformName = 'Table-To-Camera' transformNode = slicer.util.getNode(transformName) if not transformNode: # make the mrml box = vtk.vtkCubeSource() box.SetXLength(dimensions[0]) box.SetYLength(dimensions[1]) box.SetZLength(dimensions[2]) box.SetCenter(0,-dimensions[1]/2.,0) box.Update() # Create model node cursor = slicer.vtkMRMLModelNode() cursor.SetScene(slicer.mrmlScene) cursor.SetName("Cursor-Table") cursor.SetAndObservePolyData(box.GetOutput()) # Create display node cursorModelDisplay = slicer.vtkMRMLModelDisplayNode() cursorModelDisplay.SetColor((0.86274509803921573,)*3) # 'gainsboro' cursorModelDisplay.SetOpacity(0.5) cursorModelDisplay.SetScene(slicer.mrmlScene) slicer.mrmlScene.AddNode(cursorModelDisplay) cursor.SetAndObserveDisplayNodeID(cursorModelDisplay.GetID()) # Add to slicer.mrmlScene cursorModelDisplay.SetInputPolyData(box.GetOutput()) slicer.mrmlScene.AddNode(cursor) # Create transform node transformNode = slicer.vtkMRMLLinearTransformNode() transformNode.SetName(transformName) slicer.mrmlScene.AddNode(transformNode) tableToCamera = vtk.vtkMatrix4x4() tableToCamera.SetElement(1, 3, -100) transformNode.GetMatrixTransformToParent().DeepCopy(tableToCamera) cursor.SetAndObserveTransformNodeID(transformNode.GetID()) return transformNode
def transform(self,cmd): if not hasattr(self,'p'): self.p = numpy.zeros(3) self.dpdt = numpy.zeros(3) self.d2pdt2 = numpy.zeros(3) self.o = numpy.zeros(3) self.dodt = numpy.zeros(3) self.d2odt2 = numpy.zeros(3) p = urlparse.urlparse(cmd) q = urlparse.parse_qs(p.query) self.logMessage (q) dt = float(q['interval'][0]) self.d2pdt2 = 1000 * numpy.array([float(q['x'][0]), float(q['y'][0]), float(q['z'][0])]) if not hasattr(self,'g0'): self.g0 = self.d2pdt2 self.d2pdt2 = self.d2pdt2 - self.g0 self.dpdt = self.dpdt + dt * self.d2pdt2 self.p = self.p + dt * self.dpdt # TODO: integrate rotations if not hasattr(self, "idevice"): """ set up the mrml parts or use existing """ nodes = slicer.mrmlScene.GetNodesByName('idevice') if nodes.GetNumberOfItems() > 0: self.idevice = nodes.GetItemAsObject(0) nodes = slicer.mrmlScene.GetNodesByName('tracker') self.tracker = nodes.GetItemAsObject(0) else: # idevice cursor self.cube = vtk.vtkCubeSource() self.cube.SetXLength(30) self.cube.SetYLength(70) self.cube.SetZLength(5) self.cube.Update() # display node self.modelDisplay = slicer.vtkMRMLModelDisplayNode() self.modelDisplay.SetColor(1,1,0) # yellow slicer.mrmlScene.AddNode(self.modelDisplay) self.modelDisplay.SetPolyData(self.cube.GetOutput()) # Create model node self.idevice = slicer.vtkMRMLModelNode() self.idevice.SetScene(slicer.mrmlScene) self.idevice.SetName("idevice") self.idevice.SetAndObservePolyData(self.cube.GetOutput()) self.idevice.SetAndObserveDisplayNodeID(self.modelDisplay.GetID()) slicer.mrmlScene.AddNode(self.idevice) # tracker self.tracker = slicer.vtkMRMLLinearTransformNode() self.tracker.SetName('tracker') slicer.mrmlScene.AddNode(self.tracker) self.idevice.SetAndObserveTransformNodeID(self.tracker.GetID()) m = self.tracker.GetMatrixTransformToParent() m.Identity() up = numpy.zeros(3) up[2] = 1 d = self.d2pdt2 dd = d / numpy.sqrt(numpy.dot(d,d)) xx = numpy.cross(dd,up) yy = numpy.cross(dd,xx) for row in xrange(3): m.SetElement(row,0, dd[row]) m.SetElement(row,1, xx[row]) m.SetElement(row,2, yy[row]) #m.SetElement(row,3, self.p[row]) return ( "got it" )
# This module was tested on 3D Slicer version 4.3.1
def CreateSlit(self, normal, pathPolydata, ruler, ROI, slitSize): """ Here we are going to create a boxSource , the size of the 2*ROI in the X,Y and the size of the slit Size in the Z. We are then going to translate the box source to its correct location in slicer As always to visualize , a DEBUG option can be set at the top. x is L->R, y is P->A, z is I->S """ # Cube Creation roiPoints = self.utility.GetROIPoints(ROI) frontExtentIndex = self.utility.GetClosestExtent(ruler, ROI) backExtentIndex = self.utility.GetOppositeExtent(frontExtentIndex) pointA = numpy.array(roiPoints[frontExtentIndex]) pointB = numpy.array(roiPoints[backExtentIndex]) yDist = numpy.linalg.norm(pointA - pointB) numPoints = pathPolydata.GetNumberOfPoints() pointA = numpy.array(pathPolydata.GetPoint(0)) pointB = numpy.array(pathPolydata.GetPoint(numPoints - 1)) xDist = numpy.linalg.norm(pointA - pointB) zDist = slitSize # Rewording the parameter to make it easier to understand slitCube = vtk.vtkCubeSource() slitCube.SetBounds(0, xDist, -yDist, yDist, -zDist / 2, zDist / 2) # (Xmin, Xmax, Ymin, Ymax,Zmin, Zmax) # Transforming Cube transformFilter = vtk.vtkTransformFilter() transform = vtk.vtkTransform() matrix = vtk.vtkMatrix4x4() pointA = numpy.array(pathPolydata.GetPoint(0)) pointB = numpy.array(pathPolydata.GetPoint(numPoints - 1)) xVector = pointA - pointB xDist = numpy.linalg.norm(pointA - pointB) xUnitVector = (xVector[0] / xDist, xVector[1] / xDist, xVector[2] / xDist) yVector = self.utility.GetRulerVector(ruler) yDist = numpy.linalg.norm(yVector) yUnitVector = (yVector[0] / yDist, yVector[1] / yDist, yVector[2] / yDist) zVector = numpy.cross(xVector, yVector) zDist = numpy.linalg.norm(zVector) zUnitVector = (zVector[0] / zDist, zVector[1] / zDist, zVector[2] / zDist) origin = pointA = numpy.array(pathPolydata.GetPoint(numPoints - 1)) matrix.DeepCopy( ( xUnitVector[0], yUnitVector[0], zUnitVector[0], origin[0], xUnitVector[1], yUnitVector[1], zUnitVector[1], origin[1], xUnitVector[2], yUnitVector[2], zUnitVector[2], origin[2], 0, 0, 0, 1, ) ) transform.SetMatrix(matrix) transformFilter.SetTransform(transform) transformFilter.SetInputConnection(slitCube.GetOutputPort()) transformFilter.Update() self.slitPlanes.append(transformFilter.GetOutput()) if len(self.slitPlanes) == self.numberOfPaths and self.DEBUG_SLITPLANES == True: for i in range(self.numberOfPaths): self.utility.DisplayPolyData("Slit" + str(i), self.slitPlanes[i]) return transformFilter.GetOutput()
def CreateSlit(self, normal, pathPolydata, ruler, ROI, slitSize): """ Here we are going to create a boxSource , the size of the 2*ROI in the X,Y and the size of the slit Size in the Z. We are then going to translate the box source to its correct location in slicer As always to visualize , a DEBUG option can be set at the top. x is L->R, y is P->A, z is I->S """ #Cube Creation roiPoints = self.utility.GetROIPoints(ROI) frontExtentIndex = self.utility.GetClosestExtent(ruler, ROI) backExtentIndex = self.utility.GetOppositeExtent(frontExtentIndex) pointA = numpy.array(roiPoints[frontExtentIndex]) pointB = numpy.array(roiPoints[backExtentIndex]) yDist = numpy.linalg.norm(pointA - pointB) numPoints = pathPolydata.GetNumberOfPoints() pointA = numpy.array(pathPolydata.GetPoint(0)) pointB = numpy.array(pathPolydata.GetPoint(numPoints - 1)) xDist = numpy.linalg.norm(pointA - pointB) zDist = slitSize #Rewording the parameter to make it easier to understand slitCube = vtk.vtkCubeSource() slitCube.SetBounds(0, xDist, -yDist, yDist, -zDist / 2, zDist / 2) # (Xmin, Xmax, Ymin, Ymax,Zmin, Zmax) #Transforming Cube transformFilter = vtk.vtkTransformFilter() transform = vtk.vtkTransform() matrix = vtk.vtkMatrix4x4() pointA = numpy.array(pathPolydata.GetPoint(0)) pointB = numpy.array(pathPolydata.GetPoint(numPoints - 1)) xVector = pointA - pointB xDist = numpy.linalg.norm(pointA - pointB) xUnitVector = (xVector[0] / xDist, xVector[1] / xDist, xVector[2] / xDist) yVector = self.utility.GetRulerVector(ruler) yDist = numpy.linalg.norm(yVector) yUnitVector = (yVector[0] / yDist, yVector[1] / yDist, yVector[2] / yDist) zVector = numpy.cross(xVector, yVector) zDist = numpy.linalg.norm(zVector) zUnitVector = (zVector[0] / zDist, zVector[1] / zDist, zVector[2] / zDist) origin = pointA = numpy.array(pathPolydata.GetPoint(numPoints - 1)) matrix.DeepCopy( (xUnitVector[0], yUnitVector[0], zUnitVector[0], origin[0], xUnitVector[1], yUnitVector[1], zUnitVector[1], origin[1], xUnitVector[2], yUnitVector[2], zUnitVector[2], origin[2], 0, 0, 0, 1)) transform.SetMatrix(matrix) transformFilter.SetTransform(transform) transformFilter.SetInputConnection(slitCube.GetOutputPort()) transformFilter.Update() self.slitPlanes.append(transformFilter.GetOutput()) if len(self.slitPlanes ) == self.numberOfPaths and self.DEBUG_SLITPLANES == True: for i in range(self.numberOfPaths): self.utility.DisplayPolyData("Slit" + str(i), self.slitPlanes[i]) return transformFilter.GetOutput()
def transform(self, cmd): if not hasattr(self, 'p'): self.p = numpy.zeros(3) self.dpdt = numpy.zeros(3) self.d2pdt2 = numpy.zeros(3) self.o = numpy.zeros(3) self.dodt = numpy.zeros(3) self.d2odt2 = numpy.zeros(3) p = urlparse.urlparse(cmd) q = urlparse.parse_qs(p.query) self.logMessage(q) dt = float(q['interval'][0]) self.d2pdt2 = 1000 * numpy.array( [float(q['x'][0]), float(q['y'][0]), float(q['z'][0])]) if not hasattr(self, 'g0'): self.g0 = self.d2pdt2 self.d2pdt2 = self.d2pdt2 - self.g0 self.dpdt = self.dpdt + dt * self.d2pdt2 self.p = self.p + dt * self.dpdt # TODO: integrate rotations if not hasattr(self, "idevice"): """ set up the mrml parts or use existing """ nodes = slicer.mrmlScene.GetNodesByName('idevice') if nodes.GetNumberOfItems() > 0: self.idevice = nodes.GetItemAsObject(0) nodes = slicer.mrmlScene.GetNodesByName('tracker') self.tracker = nodes.GetItemAsObject(0) else: # idevice cursor self.cube = vtk.vtkCubeSource() self.cube.SetXLength(30) self.cube.SetYLength(70) self.cube.SetZLength(5) self.cube.Update() # display node self.modelDisplay = slicer.vtkMRMLModelDisplayNode() self.modelDisplay.SetColor(1, 1, 0) # yellow slicer.mrmlScene.AddNode(self.modelDisplay) self.modelDisplay.SetPolyData(self.cube.GetOutput()) # Create model node self.idevice = slicer.vtkMRMLModelNode() self.idevice.SetScene(slicer.mrmlScene) self.idevice.SetName("idevice") self.idevice.SetAndObservePolyData(self.cube.GetOutput()) self.idevice.SetAndObserveDisplayNodeID( self.modelDisplay.GetID()) slicer.mrmlScene.AddNode(self.idevice) # tracker self.tracker = slicer.vtkMRMLLinearTransformNode() self.tracker.SetName('tracker') slicer.mrmlScene.AddNode(self.tracker) self.idevice.SetAndObserveTransformNodeID(self.tracker.GetID()) m = self.tracker.GetMatrixTransformToParent() m.Identity() up = numpy.zeros(3) up[2] = 1 d = self.d2pdt2 dd = d / numpy.sqrt(numpy.dot(d, d)) xx = numpy.cross(dd, up) yy = numpy.cross(dd, xx) for row in xrange(3): m.SetElement(row, 0, dd[row]) m.SetElement(row, 1, xx[row]) m.SetElement(row, 2, yy[row]) #m.SetElement(row,3, self.p[row]) return ("got it")
def createTumorFromMarkups(self): logging.debug('createTumorFromMarkups') #self.tumorMarkups_Needle.SetDisplayVisibility(0) # Create polydata point set from markup points points = vtk.vtkPoints() cellArray = vtk.vtkCellArray() numberOfPoints = self.tumorMarkups_Needle.GetNumberOfFiducials() if numberOfPoints > 0: self.deleteLastFiducialButton.setEnabled(True) self.deleteAllFiducialsButton.setEnabled(True) self.deleteLastFiducialDuringNavigationButton.setEnabled(True) # Surface generation algorithms behave unpredictably when there are not enough points # return if there are very few points if numberOfPoints < 1: return points.SetNumberOfPoints(numberOfPoints) new_coord = [0.0, 0.0, 0.0] for i in range(numberOfPoints): self.tumorMarkups_Needle.GetNthFiducialPosition(i, new_coord) points.SetPoint(i, new_coord) cellArray.InsertNextCell(numberOfPoints) for i in range(numberOfPoints): cellArray.InsertCellPoint(i) pointPolyData = vtk.vtkPolyData() pointPolyData.SetLines(cellArray) pointPolyData.SetPoints(points) delaunay = vtk.vtkDelaunay3D() if numberOfPoints < 10: logging.debug("use glyphs") sphere = vtk.vtkCubeSource() glyph = vtk.vtkGlyph3D() glyph.SetInputData(pointPolyData) glyph.SetSourceConnection(sphere.GetOutputPort()) #glyph.SetVectorModeToUseNormal() #glyph.SetScaleModeToScaleByVector() #glyph.SetScaleFactor(0.25) delaunay.SetInputConnection(glyph.GetOutputPort()) else: delaunay.SetInputData(pointPolyData) surfaceFilter = vtk.vtkDataSetSurfaceFilter() surfaceFilter.SetInputConnection(delaunay.GetOutputPort()) smoother = vtk.vtkButterflySubdivisionFilter() smoother.SetInputConnection(surfaceFilter.GetOutputPort()) smoother.SetNumberOfSubdivisions(3) smoother.Update() forceConvexShape = True if (forceConvexShape == True): delaunaySmooth = vtk.vtkDelaunay3D() delaunaySmooth.SetInputData(smoother.GetOutput()) delaunaySmooth.Update() smoothSurfaceFilter = vtk.vtkDataSetSurfaceFilter() smoothSurfaceFilter.SetInputConnection( delaunaySmooth.GetOutputPort()) self.tumorModel_Needle.SetPolyDataConnection( smoothSurfaceFilter.GetOutputPort()) else: self.tumorModel_Needle.SetPolyDataConnection( smoother.GetOutputPort()) self.tumorModel_Needle.Modified()
def createTumorFromMarkups(self): logging.debug("createTumorFromMarkups") # self.tumorMarkups_Needle.SetDisplayVisibility(0) # Create polydata point set from markup points points = vtk.vtkPoints() cellArray = vtk.vtkCellArray() numberOfPoints = self.tumorMarkups_Needle.GetNumberOfFiducials() if numberOfPoints > 0: self.deleteLastFiducialButton.setEnabled(True) self.deleteAllFiducialsButton.setEnabled(True) self.deleteLastFiducialDuringNavigationButton.setEnabled(True) # Surface generation algorithms behave unpredictably when there are not enough points # return if there are very few points if numberOfPoints < 1: return points.SetNumberOfPoints(numberOfPoints) new_coord = [0.0, 0.0, 0.0] for i in range(numberOfPoints): self.tumorMarkups_Needle.GetNthFiducialPosition(i, new_coord) points.SetPoint(i, new_coord) cellArray.InsertNextCell(numberOfPoints) for i in range(numberOfPoints): cellArray.InsertCellPoint(i) pointPolyData = vtk.vtkPolyData() pointPolyData.SetLines(cellArray) pointPolyData.SetPoints(points) delaunay = vtk.vtkDelaunay3D() if numberOfPoints < 10: logging.debug("use glyphs") sphere = vtk.vtkCubeSource() glyph = vtk.vtkGlyph3D() glyph.SetInputData(pointPolyData) glyph.SetSourceConnection(sphere.GetOutputPort()) # glyph.SetVectorModeToUseNormal() # glyph.SetScaleModeToScaleByVector() # glyph.SetScaleFactor(0.25) delaunay.SetInputConnection(glyph.GetOutputPort()) else: delaunay.SetInputData(pointPolyData) surfaceFilter = vtk.vtkDataSetSurfaceFilter() surfaceFilter.SetInputConnection(delaunay.GetOutputPort()) smoother = vtk.vtkButterflySubdivisionFilter() smoother.SetInputConnection(surfaceFilter.GetOutputPort()) smoother.SetNumberOfSubdivisions(3) smoother.Update() forceConvexShape = True if forceConvexShape == True: delaunaySmooth = vtk.vtkDelaunay3D() delaunaySmooth.SetInputData(smoother.GetOutput()) delaunaySmooth.Update() smoothSurfaceFilter = vtk.vtkDataSetSurfaceFilter() smoothSurfaceFilter.SetInputConnection(delaunaySmooth.GetOutputPort()) self.tumorModel_Needle.SetPolyDataConnection(smoothSurfaceFilter.GetOutputPort()) else: self.tumorModel_Needle.SetPolyDataConnection(smoother.GetOutputPort()) self.tumorModel_Needle.Modified()