def ExtractMesh(outputModelNode, modelNode, colorRgb, colorTolerance): fullPolyData = modelNode.GetPolyData() pointData = fullPolyData.GetPointData() redValues = pointData.GetArray('ColorRed') greenValues = pointData.GetArray('ColorGreen') blueValues = pointData.GetArray('ColorBlue') redMaxTolerance = colorRgb[0] + colorTolerance redMinTolerance = colorRgb[0] - colorTolerance greenMaxTolerance = colorRgb[1] + colorTolerance greenMinTolerance = colorRgb[1] - colorTolerance blueMaxTolerance = colorRgb[2] + colorTolerance blueMinTolerance = colorRgb[2] - colorTolerance lengthTuples = int(redValues.GetNumberOfTuples()) selectedPointIds = vtk.vtkIdTypeArray() for pointId in range(lengthTuples): if redValues.GetValue( pointId) >= redMinTolerance and redValues.GetValue( pointId) <= redMaxTolerance and greenValues.GetValue( pointId) >= greenMinTolerance and greenValues.GetValue( pointId ) <= greenMaxTolerance and blueValues.GetValue( pointId ) >= blueMinTolerance and blueValues.GetValue( pointId) <= blueMaxTolerance: selectedPointIds.InsertNextValue(pointId) selectedPointIds.InsertNextValue(pointId) selectionNode = vtk.vtkSelectionNode() selectionNode.SetFieldType(vtk.vtkSelectionNode.POINT) selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) selectionNode.SetSelectionList(selectedPointIds) selectionNode.GetProperties().Set(vtk.vtkSelectionNode.CONTAINING_CELLS(), 1) selection = vtk.vtkSelection() selection.AddNode(selectionNode) extractSelection = vtk.vtkExtractSelection() extractSelection.SetInputData(0, fullPolyData) extractSelection.SetInputData(1, selection) extractSelection.Update() convertToPolydata = vtk.vtkDataSetSurfaceFilter() convertToPolydata.SetInputConnection(extractSelection.GetOutputPort()) convertToPolydata.Update() outputModelNode.SetAndObservePolyData(convertToPolydata.GetOutput()) if not outputModelNode.GetDisplayNode(): md2 = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(md2) outputModelNode.SetAndObserveDisplayNodeID(md2.GetID())
def ExtractMesh(outputModelNode, modelNode, colorRgb, colorTolerance): fullPolyData = modelNode.GetPolyData() pointData=fullPolyData.GetPointData() redValues = pointData.GetArray('ColorRed') greenValues = pointData.GetArray('ColorGreen') blueValues = pointData.GetArray('ColorBlue') redMaxTolerance = colorRgb[0] + colorTolerance redMinTolerance = colorRgb[0] - colorTolerance greenMaxTolerance = colorRgb[1] + colorTolerance greenMinTolerance = colorRgb[1] - colorTolerance blueMaxTolerance = colorRgb[2] + colorTolerance blueMinTolerance = colorRgb[2] - colorTolerance lengthTuples = int(redValues.GetNumberOfTuples()) selectedPointIds = vtk.vtkIdTypeArray() for pointId in range(lengthTuples): if redValues.GetValue(pointId) >= redMinTolerance and redValues.GetValue(pointId) <= redMaxTolerance and greenValues.GetValue(pointId) >= greenMinTolerance and greenValues.GetValue(pointId) <= greenMaxTolerance and blueValues.GetValue(pointId) >= blueMinTolerance and blueValues.GetValue(pointId) <= blueMaxTolerance: selectedPointIds.InsertNextValue(pointId) selectedPointIds.InsertNextValue(pointId) selectionNode = vtk.vtkSelectionNode() selectionNode.SetFieldType(vtk.vtkSelectionNode.POINT) selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) selectionNode.SetSelectionList(selectedPointIds) selectionNode.GetProperties().Set(vtk.vtkSelectionNode.CONTAINING_CELLS(), 1); selection = vtk.vtkSelection() selection.AddNode(selectionNode) extractSelection = vtk.vtkExtractSelection() extractSelection.SetInputData(0,fullPolyData) extractSelection.SetInputData(1,selection); extractSelection.Update(); convertToPolydata = vtk.vtkDataSetSurfaceFilter() convertToPolydata.SetInputConnection(extractSelection.GetOutputPort()) convertToPolydata.Update() outputModelNode.SetAndObservePolyData(convertToPolydata.GetOutput()) if not outputModelNode.GetDisplayNode(): md2 = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(md2) outputModelNode.SetAndObserveDisplayNodeID(md2.GetID())
def generateResectionVolume(self, fiducialNode, modelNode): if (fiducialNode != None): self.FiducialNode = fiducialNode self.PolyData = vtk.vtkPolyData() self.updatePoints() self.Delaunay = vtk.vtkDelaunay3D() if (vtk.VTK_MAJOR_VERSION <= 5): self.Delaunay.SetInput(self.PolyData) else: self.Delaunay.SetInputData(self.PolyData) self.Delaunay.Update() self.SurfaceFilter = vtk.vtkDataSetSurfaceFilter() self.SurfaceFilter.SetInputConnection( self.Delaunay.GetOutputPort()) self.SurfaceFilter.Update() self.Smoother = vtk.vtkButterflySubdivisionFilter() self.Smoother.SetInputConnection( self.SurfaceFilter.GetOutputPort()) self.Smoother.SetNumberOfSubdivisions(3) self.Smoother.Update() if modelNode.GetDisplayNodeID() == None: modelDisplayNode = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLModelDisplayNode") modelDisplayNode.SetColor(0, 0, 1) # Blue modelDisplayNode.BackfaceCullingOff() modelDisplayNode.SetOpacity(0.3) # Between 0-1, 1 being opaque slicer.mrmlScene.AddNode(modelDisplayNode) modelNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID()) if (vtk.VTK_MAJOR_VERSION <= 5): modelNode.SetAndObservePolyData(self.Smoother.GetOutput()) else: modelNode.SetPolyDataConnection(self.Smoother.GetOutputPort()) modelNode.Modified() self.tag = self.FiducialNode.AddObserver( 'ModifiedEvent', self.updateResectionVolume)
def generateResectionVolume(self, fiducialNode, modelNode): if (fiducialNode != None): self.FiducialNode = fiducialNode self.PolyData = vtk.vtkPolyData() self.updatePoints() self.Delaunay = vtk.vtkDelaunay3D() if (vtk.VTK_MAJOR_VERSION <= 5): self.Delaunay.SetInput(self.PolyData) else: self.Delaunay.SetInputData(self.PolyData) self.Delaunay.Update() self.SurfaceFilter = vtk.vtkDataSetSurfaceFilter() self.SurfaceFilter.SetInputConnection(self.Delaunay.GetOutputPort()) self.SurfaceFilter.Update() self.Smoother = vtk.vtkButterflySubdivisionFilter() self.Smoother.SetInputConnection(self.SurfaceFilter.GetOutputPort()) self.Smoother.SetNumberOfSubdivisions(3) self.Smoother.Update() if modelNode.GetDisplayNodeID() == None: modelDisplayNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLModelDisplayNode") modelDisplayNode.SetColor(0,0,1) # Blue modelDisplayNode.BackfaceCullingOff() modelDisplayNode.SetOpacity(0.3) # Between 0-1, 1 being opaque slicer.mrmlScene.AddNode(modelDisplayNode) modelNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID()) if (vtk.VTK_MAJOR_VERSION <= 5): modelNode.SetAndObservePolyData(self.Smoother.GetOutput()) else: modelNode.SetPolyDataConnection(self.Smoother.GetOutputPort()) modelNode.Modified() self.tag = self.FiducialNode.AddObserver('ModifiedEvent', self.updateResectionVolume)
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 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()