def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkVertexDegree(), 'Processing.', ('vtkAbstractGraph',), ('vtkAbstractGraph',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__(self, module_manager, vtk.vtkVertexDegree(), 'Processing.', ('vtkAbstractGraph', ), ('vtkAbstractGraph', ), replaceDoc=True, inputFunctions=None, outputFunctions=None)
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 loadGraph(): # ---------- # Load and construct whole graph and multi-resolution data from Matlab structure dataDir = '/Users/emonson/Programming/Matlab/EMonson/Fodava/DocumentAnalysis/Analysis/' filename = dataDir + 'X20_042709b.mat' # filename = '/Users/emonson/Programming/Python/VTK/X20_040609b.mat' X = scipy.io.loadmat(filename) # Get graph structure G out of matlab variables G = X['G'] # ---------- # Set multi-resolution level bounds in GUI sliders levelMax = G.Tree.shape[0]-1 ui_window.hSlider_level.setMinimum(1) ui_window.hSlider_level.setMaximum(levelMax) ui_window.spinBox_level.setMinimum(1) ui_window.spinBox_level.setMaximum(levelMax) # Start setting up basis function for display as subgraph ExtBasis = GTree[level,0]['ExtBasis'][0][0][0] basisMax = ExtBasis.shape[1]-1 # zero-based indices # Set particular level basis function bounds in GUI sliders ui_window.hSlider_basisIndex.setMinimum(0) ui_window.hSlider_basisIndex.setMaximum(basisMax) ui_window.spinBox_basisIndex.setMinimum(0) ui_window.spinBox_basisIndex.setMaximum(basisMax) # Build table which will become graph table = vtk.vtkTable() col0 = vtk.vtkIntArray() col0.SetName('index1') col1 = vtk.vtkIntArray() col1.SetName('index2') val = vtk.vtkDoubleArray() val.SetName('weight') Tmat = G.T # Tmat = G.W for ii in range(Tmat.nzmax): col0.InsertNextValue(Tmat.rowcol(ii)[0]) col1.InsertNextValue(Tmat.rowcol(ii)[1]) val.InsertNextValue(abs(Tmat.getdata(ii))) table.AddColumn(col0) table.AddColumn(col1) table.AddColumn(val) # Vertex links need to be done with index2 first or indexing won't be right... # TODO: Make this foolproof so that graph always ends up with correct ordering of indices... tgraph = vtk.vtkTableToGraph() tgraph.SetInput(table) tgraph.AddLinkVertex('index2', 'stuff', False) tgraph.AddLinkVertex('index1', 'stuff', False) tgraph.AddLinkEdge('index2', 'index1') rawGraph = tgraph.GetOutput() rawGraph.Update() # print graph # Load and assign whole graph pre-layout coordinates ptsFile = os.path.splitext(filename)[0] + '_pts.vtp' if os.path.exists(ptsFile): polyreader = vtk.vtkXMLPolyDataReader() polyreader.SetFileName(ptsFile) polyreader.Update() pts = polyreader.GetOutput().GetPoints() rawGraph.SetPoints(pts) # print pts strategy = vtk.vtkPassThroughLayoutStrategy() layout = vtk.vtkGraphLayout() layout.SetInput(rawGraph) layout.SetLayoutStrategy(strategy) edgeLayout = vtk.vtkEdgeLayout() edgeStrategy = vtk.vtkArcParallelEdgeStrategy() edgeStrategy.SetNumberOfSubdivisions(50) edgeLayout.SetInputConnection(layout.GetOutputPort()) edgeLayout.SetLayoutStrategy(edgeStrategy) graph = edgeLayout.GetOutput() graph.Update() # -------- # Add ExtBasis to graph data & Select particular basis function # print 'ExtBasis shape: ' + str(ExtBasis[:,basisNum].data.shape) + ' (level,basis) (' + str(level) + ',' + str(basisNum) + ')' # Indexing of ExtBasis is backwards from graph, so need to reverse with [::-1] # and array not "contiguous" if don't do .copy() Esub = ExtBasis[:,basisNum].data[::-1].copy() EsubSq = Esub**2 # Esub = N.random.random(ExtBasis[:,basisNum].data.shape[0]) # SubIdxs = (Esub > 0.001).nonzero() # SubIdxs = (Esub**2 > 0.8).nonzero() # Set ExtBasis vertex data from numpy array basisFunc = VN.numpy_to_vtk(Esub) basisFunc.SetName('ExtBasis') basisFuncSq = VN.numpy_to_vtk(EsubSq) basisFuncSq.SetName('ExtBasisSq') vertexData = graph.GetVertexData() vertexData.AddArray(basisFunc) vertexData.AddArray(basisFuncSq) selection = vtk.vtkSelectionSource() selection.SetContentType(7) # vtkSelection::THRESHOLDS # selection.SetContentType(2) # vtkSelection::PEDIGREE_IDS selection.SetFieldType(3) # vtkSelection::VERTEX selection.SetArrayName("ExtBasisSq") selection.AddThreshold(basisCutoff, 10) # TODO: There was something wrong with the indexing in the PEDIGREE_IDS selection... # for ii in SubIdxs[0]: # selection.AddID(0,ii) minmax = "(%3.2e, %3.2e)" % (EsubSq.min(), EsubSq.max()) ui_window.label_basisCutoff_minmax.setText(minmax) selection.Update() # ---------- # Back to pipeline degree = vtk.vtkVertexDegree() degree.SetInput(graph) subgraph = vtk.vtkExtractSelectedGraph() subgraph.SetRemoveIsolatedVertices(False) subgraph.SetInputConnection(degree.GetOutputPort()) subgraph.SetSelectionConnection(selection.GetOutputPort()) # +++++++++++++ graphToPoly = vtk.vtkGraphToPolyData() graphToPoly.SetInputConnection(subgraph.GetOutputPort()) edgeMapper = vtk.vtkPolyDataMapper() edgeMapper.SetInputConnection(graphToPoly.GetOutputPort()) edgeMapper.SetScalarModeToUseCellData() edgeMapper.SetScalarVisibility(False) edgeMapper.SetImmediateModeRendering(True) edgeActor = vtk.vtkActor() edgeActor.SetMapper(edgeMapper) edgeActor.SetPosition(0, 0, -0.003); lut = vtk.vtkLookupTable() lutNum = 256 lut.SetNumberOfTableValues(lutNum) ctf = vtk.vtkColorTransferFunction() ctf.SetColorSpaceToDiverging() ctf.AddRGBPoint(0.0, 0, 0, 1.0) ctf.AddRGBPoint(1.0, 1.0, 0, 0) for ii,ss in enumerate([float(xx)/float(lutNum) for xx in range(lutNum)]): cc = ctf.GetColor(ss) lut.SetTableValue(ii,cc[0],cc[1],cc[2],1.0) vertGlyph = vtk.vtkVertexGlyphFilter() vertGlyph.SetInputConnection(subgraph.GetOutputPort()) vertMapper = vtk.vtkPolyDataMapper() vertMapper.SetInputConnection(vertGlyph.GetOutputPort()) vertMapper.SetImmediateModeRendering(True) vertMapper.SetScalarModeToUsePointFieldData() vertMapper.SetLookupTable(lut) vertMapper.SelectColorArray('ExtBasis') vertMapper.Update() vertRange = vertMapper.GetInput().GetPointData().GetArray(vertMapper.GetArrayName()).GetRange() vertMapper.SetScalarRange(-1.0*vertRange[1], vertRange[1]) vertActor = vtk.vtkActor() vertActor.SetMapper(vertMapper) outlineMapper = vtk.vtkPolyDataMapper() outlineMapper.SetScalarVisibility(False) outlineMapper.SetImmediateModeRendering(True) outlineMapper.SetInputConnection(vertGlyph.GetOutputPort()) outlineActor = vtk.vtkActor() outlineActor.PickableOff() outlineActor.SetPosition(0, 0, -0.001) outlineActor.GetProperty().SetRepresentationToWireframe() outlineActor.SetMapper(outlineMapper) # Create an Actor Collection for applying visibility to group basisActorCollection = vtk.vtkActorCollection() basisActorCollection.AddItem(vertActor) # basisActorCollection.AddItem(edgeActor) basisActorCollection.AddItem(outlineActor) # Apply a theme to the views theme = vtk.vtkViewTheme.CreateMellowTheme() theme.SetLineWidth(3) theme.SetPointSize(5) theme.SetSelectedCellColor(1,1,1) theme.SetSelectedPointColor(1,1,1) theme.SetOutlineColor(0.8, 0.8, 0.8) # theme.SetPointColor(0.9, 0.7, 0.3) theme.SetCellColor(0.9, 0.7, 0.3) # theme.SetPointOpacity(0.5) # theme.SetPointHueRange(0.0, 0.15) # theme.SetPointSaturationRange(0.6, 0.8) # theme.SetPointValueRange(0.4,0.8) # theme.SetPointAlphaRange(0.2,0.8) # theme.SetPointAlphaRange(1.0,1.0) # Apply theme # vertActor.GetProperty().SetColor(theme.GetPointColor()) # vertActor.GetProperty().SetOpacity(theme.GetPointOpacity()) vertActor.GetProperty().SetPointSize(theme.GetPointSize()) outlineActor.GetProperty().SetPointSize(vertActor.GetProperty().GetPointSize()+2) outlineActor.GetProperty().SetColor(theme.GetOutlineColor()) outlineActor.GetProperty().SetOpacity(theme.GetPointOpacity()) edgeActor.GetProperty().SetColor(theme.GetCellColor()) edgeActor.GetProperty().SetOpacity(theme.GetCellOpacity()) edgeActor.GetProperty().SetLineWidth(theme.GetLineWidth()) # ---------- # Background graph skeleton graphMapper = vtk.vtkGraphMapper() graphMapper.SetInputConnection(0, degree.GetOutputPort(0)) # Apply a theme to the background graph gtheme = vtk.vtkViewTheme() gtheme.SetLineWidth(1) gtheme.SetPointSize(0) gtheme.SetCellColor(0.8, 0.8, 0.8) gtheme.SetCellOpacity(0.2) gtheme.SetOutlineColor(0.8, 0.8, 0.8) gtheme.SetPointColor(0.8, 0.8, 0.8) gtheme.SetPointOpacity(0.0) graphMapper.ApplyViewTheme(gtheme) graphActor = vtk.vtkActor() graphActor.SetMapper(graphMapper) graphActor.SetPosition(0,0,-0.005) # ---------- # Background vertices graphPoly = vtk.vtkGraphToPolyData() graphPoly.SetInputConnection(0, tgraph.GetOutputPort(0)) vertGlyph = vtk.vtkGlyph3D() vertGlyph.SetInputConnection(0, graphPoly.GetOutputPort()) glyphSource = vtk.vtkGlyphSource2D() glyphSource.SetGlyphTypeToVertex() # glyphSource.SetGlyphTypeToCircle() # glyphSource.SetScale(0.025) vertGlyph.SetInputConnection(1, glyphSource.GetOutputPort()) vertexMapper = vtk.vtkPolyDataMapper() vertexMapper.SetInputConnection(vertGlyph.GetOutputPort()) vertexActor = vtk.vtkActor() vertexActor.SetMapper(vertexMapper) vertexActor.GetProperty().SetPointSize(4) vertexActor.GetProperty().SetOpacity(0.5) vertexActor.GetProperty().SetColor(0.6, 0.6, 0.6) vertexActor.SetPosition(0, 0, -0.004) # ---------- # Vertex index labels labelMapper = vtk.vtkDynamic2DLabelMapper() labelMapper.SetInputConnection(0, graphPoly.GetOutputPort(0)) labelMapper.SetLabelModeToLabelFieldData() labelMapper.SetFieldDataName("label") labelMapper.SetLabelFormat("%s") labelMapper.GetLabelTextProperty().SetColor(0.0, 0.0, 0.0) labelActor = vtk.vtkActor2D() labelActor.SetMapper(labelMapper) # ---------- # MultiScale Graph msGraph = buildSubGraph(level) msMapper = vtk.vtkGraphMapper() msMapper.SetInput(msGraph) msMapper.SetColorEdges(True) msMapper.SetEdgeColorArrayName('weight') # Apply a theme to the background graph mtheme = vtk.vtkViewTheme() mtheme.SetLineWidth(3) mtheme.SetPointSize(11) # mtheme.SetCellColor(0.5, 0.5, 0.7) # mtheme.SetCellOpacity(0.5) mtheme.SetOutlineColor(0.8, 0.8, 0.8) mtheme.SetPointColor(0.3, 0.3, 0.6) mtheme.SetPointOpacity(1.0) mtheme.SetCellHueRange(0.67, 0.67) mtheme.SetCellSaturationRange(0.6, 0.1) mtheme.SetCellValueRange(0.5,1.0) mtheme.SetCellAlphaRange(0.2,0.8) msMapper.ApplyViewTheme(mtheme) msActor = vtk.vtkActor() msActor.SetMapper(msMapper) msActor.SetPosition(0,0,-0.002) # ---------- # Set up window and add actors view.SetLayoutStrategyToPassThrough() # view.ApplyViewTheme(theme) # view.SetupRenderWindow(win) view.GetRenderer().SetBackground(theme.GetBackgroundColor()) view.GetRenderer().SetBackground2(theme.GetBackgroundColor2()) view.GetRenderer().SetGradientBackground(True) view.GetRenderer().AddActor(vertActor) view.GetRenderer().AddActor(outlineActor) view.GetRenderer().AddActor(edgeActor) view.GetRenderer().AddActor(graphActor) view.GetRenderer().AddActor(vertexActor) view.GetRenderer().AddActor(labelActor) view.GetRenderer().AddActor(msActor) # ---------- # General interactor isty = vtk.vtkInteractorStyleRubberBand2D() # RubberBand2D assumes/needs parallel projection ON view.GetRenderer().GetActiveCamera().ParallelProjectionOn() iren = view.GetRenderWindow().GetInteractor() iren.SetInteractorStyle(isty) # Interactor style must be set before scalar bar can be shown # view.SetVertexScalarBarVisibility(True) sbActor = vtk.vtkScalarBarActor() sbActor.SetLookupTable(vertMapper.GetLookupTable()) sbActor.SetTitle(vertMapper.GetArrayName()) sbActor.SetNumberOfLabels(3) vertexScalarBar = vtk.vtkScalarBarWidget() vertexScalarBar.SetScalarBarActor(sbActor) vertexScalarBar.SetInteractor(iren) vertexScalarBar.SetDefaultRenderer(view.GetRenderer()) vertexScalarBar.SetCurrentRenderer(view.GetRenderer()) vertexScalarBar.SetEnabled(True) scalarBarRep = vertexScalarBar.GetRepresentation() scalarBarRep.SetOrientation(1) # 0 = Horizontal, 1 = Vertical scalarBarRep.GetPositionCoordinate().SetValue(0.05,0.05) scalarBarRep.GetPosition2Coordinate().SetValue(0.15,0.25) # Adding it this way gets it to show up, but it's not interactive view.GetRenderer().AddActor(sbActor) view.ResetCamera() view.Render() # ---------- # Add Actors to QListWidget to allow check and uncheck for visibility listItem0 = QtGui.QListWidgetItem() listItem0.setText('Index Labels') listItem0.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) labelActor.SetVisibility(0) listItem0.setCheckState(QtCore.Qt.Unchecked) # Put actor it in as data in the list widget item listItem0.setData(QtCore.Qt.UserRole, QtCore.QVariant(labelActor)) ui_window.listWidget.insertItem(0,listItem0) # Test retrieval of actor from list widget item # tmpItem = ui_window.listWidget.item(0) # tmpQtActor = tmpItem.data(QtCore.Qt.UserRole) # tmpActor = tmpQtActor.toPyObject() # tmpActor.SetVisibility(0) # Shorter way to add item to list widget listItem1 = QtGui.QListWidgetItem('Vertices (background)', ui_window.listWidget) listItem1.setData(QtCore.Qt.UserRole, QtCore.QVariant(vertexActor)) listItem1.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) listItem1.setCheckState(QtCore.Qt.Checked) listItem2 = QtGui.QListWidgetItem('Graph (background)', ui_window.listWidget) listItem2.setData(QtCore.Qt.UserRole, QtCore.QVariant(graphActor)) listItem2.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) listItem2.setCheckState(QtCore.Qt.Checked) listItem3 = QtGui.QListWidgetItem() listItem3.setText('Basis Function Vertices') listItem3.setData(QtCore.Qt.UserRole, QtCore.QVariant(basisActorCollection)) listItem3.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) listItem3.setCheckState(QtCore.Qt.Checked) ui_window.listWidget.insertItem(1,listItem3) listItem6 = QtGui.QListWidgetItem() listItem6.setText('Basis Function Edges') listItem6.setData(QtCore.Qt.UserRole, QtCore.QVariant(edgeActor)) listItem6.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) listItem6.setCheckState(QtCore.Qt.Checked) ui_window.listWidget.insertItem(2,listItem6) listItem4 = QtGui.QListWidgetItem() listItem4.setText('MultiScale Graph') listItem4.setData(QtCore.Qt.UserRole, QtCore.QVariant(msActor)) listItem4.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) listItem4.setCheckState(QtCore.Qt.Checked) ui_window.listWidget.insertItem(3,listItem4) listItem5 = QtGui.QListWidgetItem() listItem5.setText('Basis Function Scale Bar') listItem5.setData(QtCore.Qt.UserRole, QtCore.QVariant(sbActor)) listItem5.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) listItem5.setCheckState(QtCore.Qt.Checked) ui_window.listWidget.insertItem(3,listItem5) iren.Initialize() iren.Start()
def __init__(self, data_source): """Icicle view constructor needs a valid DataSource and will pull data from it immediately.""" self.ds = data_source SHRINK = 0.1 THICK = 1.0 tree = self.ds.GetTree() # Build view self.view = vtk.vtkIcicleView() self.view.SetRepresentationFromInput(tree) self.view.SetAreaSizeArrayName("num_in_vertex") self.view.SetAreaColorArrayName("scale") self.view.SetAreaLabelArrayName("blank") self.view.SetLabelPriorityArrayName("VertexDegree") self.view.SetAreaLabelVisibility(True) self.view.SetAreaHoverArrayName("vertex_ids") self.view.SetDisplayHoverText(True) self.view.SetShrinkPercentage(SHRINK) self.view.SetLayerThickness(THICK) self.view.UseGradientColoringOff() self.style = vtk.vtkInteractorStyleImage() self.view.SetInteractorStyle(self.style) # Parallel pipeline with no shrinkage to get TCoords TreeLevels = vtk.vtkTreeLevelsFilter() TreeLevels.SetInput(tree) VertexDegree = vtk.vtkVertexDegree() VertexDegree.SetInputConnection(TreeLevels.GetOutputPort(0)) TreeAggregation = vtk.vtkTreeFieldAggregator() TreeAggregation.LeafVertexUnitSizeOff() TreeAggregation.SetField('size') TreeAggregation.SetInputConnection(VertexDegree.GetOutputPort(0)) # Layout with shrinkage for generating geometry strategy = vtk.vtkStackedTreeLayoutStrategy() strategy.UseRectangularCoordinatesOn() strategy.SetRootStartAngle(0.0) strategy.SetRootEndAngle(15.0) strategy.SetRingThickness(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 without shrinkage for generating texture coordinates strategy0 = vtk.vtkStackedTreeLayoutStrategy() strategy0.UseRectangularCoordinatesOn() strategy0.SetRootStartAngle(0.0) strategy0.SetRootEndAngle(15.0) strategy0.SetRingThickness(THICK) # layer thickness strategy0.ReverseOn() strategy0.SetShrinkPercentage(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')) LeafIds = vertex_ids[isleaf>0] LeafXmins = poly_bounds[isleaf>0,0] XOrderedLeafIds = LeafIds[LeafXmins.argsort()] # And then grab the Wavelet Coefficients matrix sorted according to this WCimageData = self.ds.GetWaveletCoeffImage(XOrderedLeafIds) WCrange = N.array(WCimageData.GetPointData().GetScalars().GetRange()) WCext = abs(WCrange.min()) if (abs(WCrange.min()) > abs(WCrange.max())) else abs(WCrange.max()) # print WCext # Create blue to white to red lookup table lut = vtk.vtkLookupTable() lutNum = 256 lut.SetNumberOfTableValues(lutNum) lut.Build() ctf = vtk.vtkColorTransferFunction() ctf.SetColorSpaceToDiverging() ctf.AddRGBPoint(0.0, 0, 0, 1.0) ctf.AddRGBPoint(1.0, 1.0, 0, 0) for ii,ss in enumerate([float(xx)/float(lutNum) for xx in range(lutNum)]): cc = ctf.GetColor(ss) lut.SetTableValue(ii,cc[0],cc[1],cc[2],1.0) lut.SetRange(-WCext,WCext) # Set up texture with lookup table for matrix polys tex = vtk.vtkTexture() tex.SetInput(WCimageData) tex.SetLookupTable(lut) # Separate mapper and actor for textured polys map2 = vtk.vtkPolyDataMapper() map2.SetInputConnection(paf.GetOutputPort(0)) map2.ScalarVisibilityOff() act2 = vtk.vtkActor() act2.SetMapper(map2) act2.SetTexture(tex) act2.GetProperty().SetColor(1,1,1) act2.SetPickable(0) act2.SetPosition(0,0,0.1) # Add textured polys to the view ren = self.view.GetRenderer() ren.AddActor(act2) # NOTE: This is the one place I'm still hacking into the view -- to set the # normal icicle view to wireframe and set the color... # Ren has an actor2d which is a scalar bar (edge) acts = ren.GetActors() # Acts has two actors -- graph blocks (0) and labels (1) act0 = acts.GetItemAsObject(0) act0.GetProperty().SetRepresentationToWireframe() act0.GetProperty().SetLineWidth(3.0) # Apply a theme to the views theme = vtk.vtkViewTheme.CreateMellowTheme() theme.SetPointHueRange(0,0) theme.SetPointSaturationRange(0.2,0.5) theme.SetPointValueRange(0.0,0.0) theme.SetPointAlphaRange(0.0,0.0) c = N.array([255,204,0])/255.0 theme.SetSelectedPointColor(c[0],c[1],c[2]) theme.SetBackgroundColor(0.1, 0.1, 0.06) theme.SetBackgroundColor2(0.25, 0.25, 0.2) self.view.ApplyViewTheme(theme) theme.FastDelete() # Connect the annotation link to the icicle representation rep = self.view.GetRepresentation(0) # Grab annotation link to monitor selection changes self.link = rep.GetAnnotationLink() # If you don't set the FieldType explicitly it ends up as UNKNOWN (as of 21 Feb 2010) # See vtkSelectionNode doc for field and content type enum values # enum SelectionContent { # SELECTIONS, GLOBALIDS, PEDIGREEIDS, VALUES, # INDICES, FRUSTUM, LOCATIONS, THRESHOLDS, # BLOCKS # } # enum SelectionField { # CELL, POINT, FIELD, VERTEX, # EDGE, ROW # } # Note: This may be the defaults, anyway, for the IcicleView annotation link self.link.GetCurrentSelection().GetNode(0).SetFieldType(3) # Vertex self.link.GetCurrentSelection().GetNode(0).SetContentType(2) # Pedigree Ids # TEST: Set up callback to test icicle view selection IDs self.link.AddObserver("AnnotationChangedEvent", self.IcicleSelectionCallback) self.view.GetRenderer().GetActiveCamera().ParallelProjectionOn() self.view.ResetCamera() self.view.Render()