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())
Esempio n. 4
0
    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')