def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkExtractSelectedPolyDataIds(), 'Processing.', ('vtkPolyData', 'vtkSelection'), ('vtkPolyData',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def rasterizeFibers(self,fiberNode,labelNode,labelValue=1,samplingDistance=0.1): """Trace through the given fiber bundles and set the corresponding pixels in the given labelNode volume""" print('rasterizing...') rasToIJK = vtk.vtkMatrix4x4() labelNode.GetRASToIJKMatrix(rasToIJK) labelArray = slicer.util.array(labelNode.GetID()) polyData = fiberNode.GetPolyData() cellCount = polyData.GetNumberOfCells() selection = vtk.vtkSelection() selectionNode = vtk.vtkSelectionNode() selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL) selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) extractor = vtk.vtkExtractSelectedPolyDataIds() extractor.SetInputData(0, polyData) resampler = vtk.vtkPolyDataPointSampler() resampler.GenerateEdgePointsOn() resampler.GenerateVertexPointsOff() resampler.GenerateInteriorPointsOff() resampler.GenerateVerticesOff() resampler.SetDistance(samplingDistance) cellIds = vtk.vtkIdTypeArray() # as a compromise between memory blowup (for large fiberbundles) and not # eating time in the python loop, resample CELLS_TO_PROCESS at once. CELLS_TO_PROCESS = 100 for startCellId in xrange(0, cellCount, CELLS_TO_PROCESS): # generate list of cell Ids to sample cellIdsAr = numpy.arange(startCellId, min(cellCount, startCellId + CELLS_TO_PROCESS)) cellIds.SetVoidArray(cellIdsAr, cellIdsAr.size, 1) # update the selection node to extract those cells selectionNode.SetSelectionList(cellIds) selection.AddNode(selectionNode) selection.Modified() extractor.SetInputData(1, selection) extractor.Update() resampler.SetInputConnection(extractor.GetOutputPort()) resampler.Update() # get the resampler output # note: to test without resampling, just use # `pdSubset = extractor.GetOutput()` instead pdSubset = resampler.GetOutput() pointCount = pdSubset.GetNumberOfPoints() points = pdSubset.GetPoints() for pointIndex in xrange(pointCount): point = points.GetPoint(pointIndex) ijkFloat = rasToIJK.MultiplyPoint(point+(1,))[:3] # skip any negative indices to avoid wrap-around # to the other side of the image. if (any(coord < 0 for coord in ijkFloat)): continue ijk = [int(round(element)) for element in ijkFloat] ijk.reverse() try: # paint the voxels labelArray[tuple(ijk)] = labelValue except IndexError: pass # reset the selection node selection.RemoveAllNodes() labelNode.GetImageData().Modified() labelNode.Modified() print('finished')
def LoadData(self): # Remove all old actors from renderer self.renderer.RemoveAllViewProps() # Put back nav menu menu_actor_list = self.menu.GetActorList() for m_actor in menu_actor_list: self.renderer.AddActor(m_actor) tree = self.ds.GetTree() # Parallel pipeline with no shrinkage to get TCoords self.TreeLevels = vtk.vtkTreeLevelsFilter() self.TreeLevels.SetInput(tree) VertexDegree = vtk.vtkVertexDegree() VertexDegree.SetInputConnection(self.TreeLevels.GetOutputPort(0)) TreeAggregation = vtk.vtkTreeFieldAggregator() TreeAggregation.LeafVertexUnitSizeOff() TreeAggregation.SetField('size') TreeAggregation.SetInputConnection(VertexDegree.GetOutputPort(0)) # Layout without shrinkage for generating texture coordinates strategy = vtk.vtkStackedTreeLayoutStrategy() strategy.UseRectangularCoordinatesOn() strategy.SetRootStartAngle(0.0) strategy.SetRootEndAngle(15.0) strategy.SetRingThickness(self.THICK) # layer thickness strategy.ReverseOn() strategy.SetShrinkPercentage(0.0) layout = vtk.vtkAreaLayout() layout.SetLayoutStrategy(strategy) layout.SetInputConnection(TreeAggregation.GetOutputPort(0)) layout.SetAreaArrayName("area") layout.SetSizeArrayName("num_in_vertex") areapoly = vtk.vtkTreeMapToPolyData() areapoly.SetInputConnection(layout.GetOutputPort(0)) areapoly.SetAddNormals(0) areapoly.SetInputArrayToProcess( 0, 0, 0, 4, "area") # 4 = vtkDataObject::FIELD_ASSOCIATION_VERTICES texPlane = vtk.vtkTextureMapToPlane() texPlane.SetInputConnection(areapoly.GetOutputPort(0)) texPlane.AutomaticPlaneGenerationOn() texPlane.Update() # Layout with shrinkage for generating geometry strategy0 = vtk.vtkStackedTreeLayoutStrategy() strategy0.UseRectangularCoordinatesOn() strategy0.SetRootStartAngle(0.0) strategy0.SetRootEndAngle(15.0) strategy0.SetRingThickness(self.THICK) # layer thickness strategy0.ReverseOn() strategy0.SetShrinkPercentage(self.SHRINK) layout0 = vtk.vtkAreaLayout() layout0.SetLayoutStrategy(strategy0) layout0.SetInputConnection(TreeAggregation.GetOutputPort(0)) layout0.SetAreaArrayName("area") layout0.SetSizeArrayName("num_in_vertex") areapoly0 = vtk.vtkTreeMapToPolyData() areapoly0.SetAddNormals(0) areapoly0.SetInputConnection(layout0.GetOutputPort(0)) areapoly0.SetInputArrayToProcess( 0, 0, 0, 4, "area") # 4 = vtkDataObject::FIELD_ASSOCIATION_VERTICES areapoly0.Update() # Copy over texture coordinates def transferTCoords(): input = paf.GetInputDataObject(0,0) refin = paf.GetInputList().GetItem(0) output = paf.GetPolyDataOutput() TCorig = refin.GetPointData().GetTCoords() TC = vtk.vtkFloatArray() TC.SetNumberOfComponents(TCorig.GetNumberOfComponents()) TC.SetNumberOfTuples(TCorig.GetNumberOfTuples()) TC.SetName('Texture Coordinates') for ii in range(TCorig.GetNumberOfTuples()): ff = TCorig.GetTuple2(ii) TC.SetTuple2(ii,ff[0],ff[1]) output.GetPointData().AddArray(TC) output.GetPointData().SetActiveTCoords('Texture Coordinates') paf = vtk.vtkProgrammableAttributeDataFilter() paf.SetInput(areapoly0.GetOutput()) paf.AddInput(texPlane.GetOutput()) paf.SetExecuteMethod(transferTCoords) # Need to find proper ordering of wavelet coeffs based on icicle layout # tree.GetVertexData().GetArray('area') is 4-component (Xmin,Xmax,Ymin,Ymax) print 'Reordering wavelet coeffs' out_polys = areapoly.GetOutputDataObject(0) isleaf = VN.vtk_to_numpy(out_polys.GetCellData().GetArray('leaf')) poly_bounds = VN.vtk_to_numpy(out_polys.GetCellData().GetArray('area')) vertex_ids = VN.vtk_to_numpy(out_polys.GetCellData().GetArray('vertex_ids')) self.LeafIds = vertex_ids[isleaf>0] self.LeafXmins = poly_bounds[isleaf>0,0] self.XOrderedLeafIds = self.LeafIds[self.LeafXmins.argsort()] # Grab texture images and color map self.GrabTextureImagesAndLUT() # For each node and corresponding image data in self.WCimageDataList, need to create a texture, # then pull out the correct rectangle from areapoly0 (using vtkExtractSelectedPolyDataIds # and create a mapper and actor and apply the texture. self.texture_list = [] self.tex_mapper_list = [] self.tex_actor_list = [] for ii in range(len(self.WCimageDataList)): # Set up texture with lookup table for matrix polys tex = vtk.vtkTexture() tex.SetInput(self.WCimageDataList[ii]) tex.SetLookupTable(self.lut) self.texture_list.append(tex) # Grab correct poly out of areapoly0 sel = vtk.vtkSelection() node = vtk.vtkSelectionNode() node.SetContentType(4) # 4 = indices node.SetFieldType(0) # 0 = cell id_array = N.array([ii],dtype='int64') id_list = VN.numpy_to_vtkIdTypeArray(id_array) node.SetSelectionList(id_list) sel.AddNode(node) ext_id_poly = vtk.vtkExtractSelectedPolyDataIds() ext_id_poly.SetInput(1, sel) ext_id_poly.SetInputConnection(0, areapoly0.GetOutputPort(0)) # ext_id_poly.Update() # print ext_id_poly.GetOutput() poly_tm = vtk.vtkTextureMapToPlane() poly_tm.SetInputConnection(ext_id_poly.GetOutputPort(0)) poly_tm.AutomaticPlaneGenerationOn() poly_tm.Update() # Separate mapper and actor for textured polys map2 = vtk.vtkPolyDataMapper() map2.SetInputConnection(poly_tm.GetOutputPort(0)) map2.ScalarVisibilityOff() self.tex_mapper_list.append(map2) act2 = vtk.vtkActor() act2.SetMapper(self.tex_mapper_list[ii]) act2.SetTexture(self.texture_list[ii]) act2.GetProperty().SetColor(1,1,1) act2.SetPickable(0) act2.SetPosition(0,0,0.1) # ??? self.tex_actor_list.append(act2) # Add textured polys to the view self.renderer.AddActor(self.tex_actor_list[ii]) # Layout with shrinkage for generating outline geometry for showing selections self.applycolors1 = vtk.vtkApplyColors() self.applycolors1.SetInputConnection(0,layout0.GetOutputPort(0)) self.applycolors1.AddInputConnection(1,self.output_link.GetOutputPort(0)) self.applycolors1.SetDefaultPointColor(self.theme.GetPointColor()) self.applycolors1.SetDefaultPointOpacity(self.theme.GetPointOpacity()) self.applycolors1.SetSelectedPointColor(self.theme.GetSelectedPointColor()) self.applycolors1.SetSelectedPointOpacity(self.theme.GetSelectedPointOpacity()) self.areapoly1 = vtk.vtkTreeMapToPolyData() self.areapoly1.SetInputConnection(self.applycolors1.GetOutputPort(0)) self.areapoly1.SetAddNormals(0) self.areapoly1.SetInputArrayToProcess( 0, 0, 0, 4, "area") # 4 = vtkDataObject::FIELD_ASSOCIATION_VERTICES # Separate mapper and actor for icicle polys outlines (pickable) map = vtk.vtkPolyDataMapper() map.SetInputConnection(self.areapoly1.GetOutputPort(0)) map.SetScalarModeToUseCellFieldData() map.SelectColorArray("vtkApplyColors color") map.SetScalarVisibility(True) act = vtk.vtkActor() act.SetMapper(map) act.GetProperty().SetColor(1,1,1) act.SetPickable(True) act.SetPosition(0,0,0) act.GetProperty().SetRepresentationToWireframe() act.GetProperty().SetLineWidth(4.0) self.icicle_actor = act # Add actor for selection highlight outlines self.renderer.AddActor(act) # Now need to set up data for generating "selection lines" which come from # xy or pcoords chart. Basic method is to create a new scalar array out of x-coord # of the texture coordinates, then do a Delaunay2D on the shrunken polys and contour # that at values obtained by finding what normalized distance along data set are # selected pedigree ids. self.calc = vtk.vtkArrayCalculator() self.calc.SetInputConnection(paf.GetOutputPort()) self.calc.SetAttributeModeToUsePointData() self.calc.AddScalarVariable("tcoords_X", "Texture Coordinates", 0) self.calc.SetFunction("tcoords_X") self.calc.SetResultArrayName("tcx") # self.calc.Update() # print VN.vtk_to_numpy(self.calc.GetOutput().GetPointData().GetArray('tcx')) self.group_contour = vtk.vtkContourFilter() self.group_contour.SetInputConnection(self.calc.GetOutputPort(0)) self.group_contour.SetInputArrayToProcess(0,0,0,0,'tcx') self.highlight_contour = vtk.vtkContourFilter() self.highlight_contour.SetInputConnection(self.calc.GetOutputPort(0)) self.highlight_contour.SetInputArrayToProcess(0,0,0,0,'tcx') # Separate mapper and actor group selection (pcoords or xy) lines map3 = vtk.vtkPolyDataMapper() map3.SetInputConnection(self.group_contour.GetOutputPort(0)) map3.SetScalarVisibility(0) act3 = vtk.vtkActor() act3.SetMapper(map3) act3.SetPickable(False) act3.SetPosition(0,0,0.2) act3.GetProperty().SetRepresentationToWireframe() act3.GetProperty().SetLineWidth(2.0) act3.GetProperty().SetColor(1,0,0) act3.GetProperty().SetOpacity(0.6) self.group_actor = act3 # Add actor for selection highlight outlines self.renderer.AddActor(act3) # Separate mapper and actor for individual (image_flow) selection highlight map4 = vtk.vtkPolyDataMapper() map4.SetInputConnection(self.highlight_contour.GetOutputPort(0)) map4.SetScalarVisibility(0) act4 = vtk.vtkActor() act4.SetMapper(map4) act4.SetPickable(False) act4.SetPosition(0,0,0.25) act4.GetProperty().SetRepresentationToWireframe() act4.GetProperty().SetLineWidth(3.0) act4.GetProperty().SetColor(0,0.5,1) act4.GetProperty().SetOpacity(0.6) self.highlight_actor = act4 # Add actor for selection highlight outlines self.renderer.AddActor(act4) # Get Ordered fractional positions for pedigree ids (for setting contour values) self.ped_id_fracs = self.ds.GetIdsFractionalPosition(self.XOrderedLeafIds) # Clear out selections on data change self.output_link.GetCurrentSelection().RemoveAllNodes() self.output_link.InvokeEvent("AnnotationChangedEvent") self.renderer.ResetCamera(self.icicle_actor.GetBounds())
def rasterizeFibers(self, fiberNode, labelNode, labelValue=1, samplingDistance=0.1): """Trace through the given fiber bundles and set the corresponding pixels in the given labelNode volume""" print('rasterizing...') rasToIJK = vtk.vtkMatrix4x4() labelNode.GetRASToIJKMatrix(rasToIJK) labelArray = slicer.util.array(labelNode.GetID()) polyData = fiberNode.GetPolyData() cellCount = polyData.GetNumberOfCells() selection = vtk.vtkSelection() selectionNode = vtk.vtkSelectionNode() selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL) selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) extractor = vtk.vtkExtractSelectedPolyDataIds() extractor.SetInputData(0, polyData) resampler = vtk.vtkPolyDataPointSampler() resampler.GenerateEdgePointsOn() resampler.GenerateVertexPointsOff() resampler.GenerateInteriorPointsOff() resampler.GenerateVerticesOff() resampler.SetDistance(samplingDistance) cellIds = vtk.vtkIdTypeArray() # as a compromise between memory blowup (for large fiberbundles) and not # eating time in the python loop, resample CELLS_TO_PROCESS at once. CELLS_TO_PROCESS = 100 for startCellId in xrange(0, cellCount, CELLS_TO_PROCESS): # generate list of cell Ids to sample cellIdsAr = numpy.arange(startCellId, min(cellCount, startCellId + CELLS_TO_PROCESS), dtype=vtk.util.numpy_support.ID_TYPE_CODE) cellIds.SetVoidArray(cellIdsAr, cellIdsAr.size, 1) # update the selection node to extract those cells selectionNode.SetSelectionList(cellIds) selection.AddNode(selectionNode) selection.Modified() extractor.SetInputData(1, selection) extractor.Update() resampler.SetInputConnection(extractor.GetOutputPort()) resampler.Update() # get the resampler output # note: to test without resampling, just use # `pdSubset = extractor.GetOutput()` instead pdSubset = resampler.GetOutput() pointCount = pdSubset.GetNumberOfPoints() points = pdSubset.GetPoints() for pointIndex in xrange(pointCount): point = points.GetPoint(pointIndex) ijkFloat = rasToIJK.MultiplyPoint(point + (1, ))[:3] # skip any negative indices to avoid wrap-around # to the other side of the image. if (any(coord < 0 for coord in ijkFloat)): continue ijk = [int(round(element)) for element in ijkFloat] ijk.reverse() try: # paint the voxels labelArray[tuple(ijk)] = labelValue except IndexError: pass # reset the selection node selection.RemoveAllNodes() labelNode.GetImageData().Modified() labelNode.Modified() print('finished')