Hi All,<br><br>I hope this is a newbie question. I've searched the archives so I apologize if I missed something.<br><br>I have a pipeline that renders a graph using spheres for vertices and the tube filter for the edges. I would like to be able to use a rubber band interactor and select a few nodes or edges, map back to the original nodes and edges in my graph, and do something intelligent with those nodes and edges. Pretty normal graph selection scenario, I would expect. I would LOVE it if I'm just being an idiot. :) Also, any comments on my VTK code are very much appreciated. I'm a total VTK newbie.<br>
<br>I am currently having these problems. All help is really, really appreciated.<br>1. My interactor is obviously doing *something* because it draws the rubber band line, but I don't get a selection callback from rubber banding nor does it color the selected nodes (I do get a callback when I press 'p' in the render window, though.) So something is not quite right.<br>
2. Assuming I can get that to work, how do I map back from one of the two actors (vertex actor with sphere source glyph and edges with a tube filter) back to the original nodes and edges?<br><br>Thanks everyone-<br>-denny-<br>
<br><br><br>-------------------------------------<br>--Code - I hope someone finds this useful as well as can find my bug. :)<br>--P.S. This is in C# for the Activiz VTK port, but all of the examples I've seen port perfectly. So if you're not a C# person, feel free to squint your eyes and pretend it's python. :)<br>
-------------------------------------<br><br> vtkMutableDirectedGraph g;<br> vtkGraphLayout layout;<br> RenderWindowControl mRenWinCtrl;<br><br><br> //initial load at the beginning of time.<br>
void Form2_Load(object sender, EventArgs e)<br> {<br> layout = vtkGraphLayout.New();<br> var strategy = vtkForceDirectedLayoutStrategy.New();<br> strategy.ThreeDimensionalLayoutOn();<br>
layout.SetLayoutStrategy(strategy);<br><br><br> RefreshGraph();<br><br> layout.SetInput(g);<br> layout.Modified();<br> layout.Update();<br><br> SetupMyPipeline();<br>
<br> <br> }<br><br><br> //this function just regenerates a new random graph when a button is pressed.<br> private void mCreateGraphButton_Click(object sender, EventArgs e)<br> {<br>
RefreshGraph();<br> <br> layout.SetInput(g);<br> layout.Modified();<br> layout.Update();<br><br> mRenWinCtrl.RenderWindow.Modified();<br> mRenWinCtrl.RenderWindow.Render();<br>
}<br><br><br><br> private void RefreshGraph()<br> {<br> /**************************************************************/<br> g = new vtkMutableDirectedGraph();<br><br> List<long> ids = new List<long>();<br>
for (int i = 0; i < 100; i++)<br> {<br> long id = g.AddVertex();<br> ids.Add(id);<br> }<br><br> Random rand = new Random();<br> long edgeCounter = 0;<br>
<br><br> //randomly link up some vertices to make the topology interesting<br> foreach (long id1 in ids)<br> {<br> foreach (long id2 in ids)<br> {<br> if (id1 != id2 && rand.NextDouble() < .01)<br>
{<br> g.AddGraphEdge(id1, id2);<br> edgeCounter++;<br> }<br> }<br> }<br><br><br> }<br><br><br> private void SetupMyPipeline()<br>
{<br> <br> ///////////////////////////////<br> //edge handling<br> var edge_geom = vtkGraphToPolyData.New();<br> edge_geom.SetInputConnection(layout.GetOutputPort());<br>
edge_geom.EdgeGlyphOutputOn();<br> edge_geom.SetEdgeGlyphPosition(.5);<br> edge_geom.Update();<br><br><br> var tube_filter = vtkTubeFilter.New();<br> tube_filter.SetInput(edge_geom.GetOutput());<br>
tube_filter.SetRadius(.01);<br> tube_filter.SetNumberOfSides(10);<br><br><br> var edge_mapper = vtkPolyDataMapper.New();<br> edge_mapper.SetInput(tube_filter.GetOutput());<br>
edge_mapper.Update();<br>
<br> var edge_actor = vtkActor.New();<br> edge_actor.SetMapper(edge_mapper);<br> edge_actor.GetProperty().SetColor(.4, .4, .6);<br> //////////////////////////////////////////////<br>
<br><br><br><br> ////////////////////////////////////<br> //vertex handling<br> var vertex_geom = vtkGraphToPoints.New();<br> vertex_geom.SetInputConnection(layout.GetOutputPort());<br>
<br> var vertex_sphere = vtkSphereSource.New();<br> vertex_sphere.SetRadius(.025);<br><br> var vertex_glyph = vtkGlyph3D.New();<br> vertex_glyph.SetInputConnection(vertex_geom.GetOutputPort());<br>
vertex_glyph.SetSource(vertex_sphere.GetOutput());<br><br> var vertex_mapper = vtkPolyDataMapper.New();<br> vertex_mapper.SetInputConnection(vertex_glyph.GetOutputPort());<br><br> var vertex_actor = vtkActor.New();<br>
vertex_actor.SetMapper(vertex_mapper);<br> vertex_actor.GetProperty().SetColor(0, 0, 1);<br> ///////////////////////////////////////////////////<br><br><br><br> //render it<br>
var ren = vtkRenderer.New();<br> ren.AddActor(edge_actor);<br> ren.AddActor(vertex_actor);<br> ren.ResetCamera();<br> mRenWinCtrl.RenderWindow.AddRenderer(ren);<br>
<br>
<br> //picking<br> var picker = vtkAreaPicker.New();<br> picker.PickEvt += new vtkObject.vtkObjectEventHandler(picker_PickEvt);<br> picker.AddPickList(edge_actor);<br> picker.AddPickList(vertex_actor);<br>
mRenWinCtrl.RenderWindow.GetInteractor().SetPicker(picker);<br><br> //interactor<br> var interactorStyle = vtkInteractorStyleRubberBand3D.New();<br> interactorStyle.SetPickColor(.5, .1, .9);<br>
mRenWinCtrl.RenderWindow.GetInteractor().SetInteractorStyle(interactorStyle);<br> mRenWinCtrl.RenderWindow.GetInteractor().SetRenderWindow(mRenWinCtrl.RenderWindow);<br> mRenWinCtrl.RenderWindow.GetInteractor().Start();<br>
<br> }<br><br><br> //this never gets called except when I press 'p' in the render window.<br> //But it never gets called via the rubber banding.<br> void picker_PickEvt(vtkObject sender, vtkObjectEventArgs e)<br>
{<br> vtkAreaPicker picker = sender as vtkAreaPicker;<br> vtkProp3DCollection collection = picker.GetProp3Ds();<br> int num = collection.GetNumberOfItems();<br> for (int i = 0; i < num; i++)<br>
{<br> var prop = collection.GetNextProp3D();<br> }<br> }<br><br><br>