Commit 73639630 authored by Jason Shepherd's avatar Jason Shepherd

ENH: Add a GML graph reader supplied by David Duke at University of Leeds

ENH: Add a new 3D graph layout strategy from David Duke at University of Leeds (vtkSpanTreeLayoutStrategy)
ENH: Add updated tests using the 3D layout in the graph layout view
ENH: Add python examples using the graph layout view for the new strategy
parent 8477fd2e
This diff is collapsed.
from vtk import *
reader = vtkXGMLReader()
reader.SetFileName("fsm.gml")
reader.Update()
strategy = vtkSpanTreeLayoutStrategy()
strategy.DepthFirstSpanningTreeOn()
view = vtkGraphLayoutView()
view.AddRepresentationFromInputConnection(reader.GetOutputPort())
view.SetVertexLabelArrayName("vertex id")
view.SetVertexLabelVisibility(True)
view.SetVertexColorArrayName("vertex id")
view.SetColorVertices(True)
view.SetLayoutStrategy( strategy )
view.SetInteractionModeTo3D() # Left mouse button causes 3D rotate instead of zoom
view.SetLabelPlacementModeToLabelPlacer()
theme = vtkViewTheme.CreateMellowTheme()
theme.SetCellColor(.2,.2,.6)
theme.SetLineWidth(2)
theme.SetPointSize(10)
view.ApplyViewTheme(theme)
theme.FastDelete()
window = vtkRenderWindow()
window.SetSize(600, 600)
view.SetupRenderWindow(window)
view.GetRenderer().ResetCamera()
window.Render()
#Here's the window with David's original layout methodology
# Aside from the theme elements in the view above, the notable
# difference between the two views is the angling on the edges.
layout = vtkGraphLayout()
layout.SetLayoutStrategy(strategy)
layout.SetInputConnection(reader.GetOutputPort())
edge_geom = vtkGraphToPolyData()
edge_geom.SetInputConnection(layout.GetOutputPort())
vertex_geom = vtkGraphToPoints()
vertex_geom.SetInputConnection(layout.GetOutputPort())
# Vertex pipeline - mark each vertex with a cube glyph
cube = vtkCubeSource()
cube.SetXLength(0.3)
cube.SetYLength(0.3)
cube.SetZLength(0.3)
glyph = vtkGlyph3D()
glyph.SetInputConnection(vertex_geom.GetOutputPort())
glyph.SetSource(cube.GetOutput())
gmap = vtkPolyDataMapper()
gmap.SetInputConnection(glyph.GetOutputPort())
gact = vtkActor()
gact.SetMapper(gmap)
gact.GetProperty().SetColor(0,0,1)
# Edge pipeline - map edges to lines
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(edge_geom.GetOutputPort())
actor = vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(0.4,0.4,0.6)
# Renderer, window, and interaction
ren = vtkRenderer()
ren.AddActor(actor)
ren.AddActor(gact)
ren.ResetCamera()
renWin = vtkRenderWindow()
renWin.AddRenderer(ren)
renWin.SetSize(800,550)
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
#iren.Start()
window.GetInteractor().Start()
from vtk import *
source = vtkRandomGraphSource()
source.SetNumberOfVertices(150)
source.SetEdgeProbability(0.01)
source.SetUseEdgeProbability(True)
source.SetStartWithTree(True)
view = vtkGraphLayoutView()
view.AddRepresentationFromInputConnection(source.GetOutputPort())
view.SetVertexLabelArrayName("vertex id")
view.SetVertexLabelVisibility(True)
view.SetVertexColorArrayName("vertex id")
view.SetColorVertices(True)
view.SetLayoutStrategyToSpanTree()
view.SetInteractionModeTo3D() # Left mouse button causes 3D rotate instead of zoom
view.SetLabelPlacementModeToLabelPlacer()
theme = vtkViewTheme.CreateMellowTheme()
theme.SetCellColor(.2,.2,.6)
theme.SetLineWidth(2)
theme.SetPointSize(10)
view.ApplyViewTheme(theme)
theme.FastDelete()
window = vtkRenderWindow()
window.SetSize(600, 600)
view.SetupRenderWindow(window)
view.GetRenderer().ResetCamera()
window.Render()
window.GetInteractor().Start()
......@@ -77,6 +77,7 @@ vtkSimple2DLayoutStrategy.cxx
vtkSliceAndDiceLayoutStrategy.cxx
vtkSplineGraphEdges.cxx
vtkSquarifyLayoutStrategy.cxx
vtkSpanTreeLayoutStrategy.cxx
vtkStackedTreeLayoutStrategy.cxx
vtkStatisticsAlgorithm.cxx
vtkStringToCategory.cxx
......@@ -96,6 +97,7 @@ vtkTreeRingToPolyData.cxx
vtkTulipReader.cxx
vtkUnivariateStatisticsAlgorithm.cxx
vtkVertexDegree.cxx
vtkXGMLReader.cxx
vtkXMLTreeReader.cxx
)
......
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSpanTreeLayoutStrategy.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
//-------------------------------------------------------------------------
//Copyright 2008 Sandia Corporation.
//Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
//the U.S. Government retains certain rights in this software.
//-------------------------------------------------------------------------
// .NAME vtkSpanTreeLayoutStrategy
// .SECTION Description
// vtkSpanTreeLayout is a strategy for drawing directed graphs that
// works by first extracting a spanning tree (more accurately, a
// spanning forest), and using this both to position graph vertices
// and to plan the placement of non-tree edges. The latter are drawn
// with the aid of edge points to produce a tidy drawing.
//
// The approach is best suited to "quasi-trees", graphs where the number
// of edges is of the same order as the number of nodes; it is less well
// suited to denser graphs. The boolean flag DepthFirstSpanningTree
// determines whether a depth-first or breadth-first strategy is used to
// construct the underlying forest, and the choice of strategy affects
// the output layout significantly. Informal experiments suggest that
// the breadth-first strategy is better for denser graphs.
//
// Different layouts could also be produced by plugging in alternative
// tree layout strategies. To work with the method of routing non-tree
// edges, any strategy should draw a tree so that levels are equally
// spaced along the z-axis, precluding for example the use of a radial
// or balloon layout.
//
// vtkSpanTreeLayout is based on an approach to 3D graph layout first
// developed as part of the "tulip" tool by Dr. David Auber at LaBRI,
// U.Bordeaux: see www.tulip-software.org
//
// This implementation departs from the original version in that:
// (a) it is reconstructed to use Titan/VTK data structures;
// (b) it uses a faster method for dealing with non-tree edges,
// requiring at most two edge points per edge
// (c) allows for plugging in different tree layout methods
// (d) allows selection of two different strategies for building
// the underlying layout tree, which can yield significantly
// different results depending on the data.
//
// .SECTION Thanks
// Thanks to David Duke from the University of Leeds for providing this
// implementation.
#ifndef __vtkSpanTreeLayoutStrategy_h
#define __vtkSpanTreeLayoutStrategy_h
#include "vtkGraphLayoutStrategy.h"
#include "vtkPoints.h"
class VTK_INFOVIS_EXPORT vtkSpanTreeLayoutStrategy : public vtkGraphLayoutStrategy
{
public:
static vtkSpanTreeLayoutStrategy *New();
vtkTypeRevisionMacro(vtkSpanTreeLayoutStrategy, vtkGraphLayoutStrategy);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Set the strategy that is to be used in laying out the
// underlying spanning tree. For sensible results, any
// tree layout used should place each layer of the tree
// in a single X-Y plane.
// By default, vtkConeTreeLayoutStrategy is used.
vtkSetObjectMacro(TreeLayout,vtkGraphLayoutStrategy);
vtkGetObjectMacro(TreeLayout,vtkGraphLayoutStrategy);
// Description:
// If set, base the layout on a depth-first spanning tree,
// rather than the default breadth-first spanning tree.
// Switching between DFT and BFT may significantly change
// the layout, and choice must be made on a per-graph basis.
// Default value is off.
vtkSetMacro(DepthFirstSpanningTree, bool);
vtkGetMacro(DepthFirstSpanningTree, bool);
vtkBooleanMacro(DepthFirstSpanningTree, bool);
// Description:
// Perform the layout.
void Layout();
protected:
vtkSpanTreeLayoutStrategy();
~vtkSpanTreeLayoutStrategy();
vtkGraphLayoutStrategy *TreeLayout;
bool DepthFirstSpanningTree;
private:
vtkSpanTreeLayoutStrategy(const vtkSpanTreeLayoutStrategy&); // Not implemented.
void operator=(const vtkSpanTreeLayoutStrategy&); // Not implemented.
};
#endif
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkXGMLReader.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
//-------------------------------------------------------------------------
//Copyright 2008 Sandia Corporation.
//Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
//the U.S. Government retains certain rights in this software.
//-------------------------------------------------------------------------
// .NAME vtkXGMLReader - Reads XGML graph files.
// This reader is developed for a simple graph file format based
// loosely on the "GML" notation. This implementation is based
// heavily on the vtkTulipReader class that forms part of the
// Titan toolkit.
// .SECTION Thanks
// Thanks to David Duke from the University of Leeds for providing this
// implementation.
#ifndef _vtkXGMLReader_h
#define _vtkXGMLReader_h
#include "vtkUndirectedGraphAlgorithm.h"
class VTK_INFOVIS_EXPORT vtkXGMLReader : public vtkUndirectedGraphAlgorithm
{
public:
static vtkXGMLReader *New();
vtkTypeRevisionMacro(vtkXGMLReader, vtkUndirectedGraphAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// The XGML file name.
vtkGetStringMacro(FileName);
vtkSetStringMacro(FileName);
protected:
vtkXGMLReader();
~vtkXGMLReader();
virtual int RequestData(
vtkInformation *,
vtkInformationVector **,
vtkInformationVector *);
private:
char* FileName;
vtkXGMLReader(const vtkXGMLReader&); // Not implemented.
void operator=(const vtkXGMLReader&); // Not implemented.
};
#endif // _vtkXGMLReader_h
......@@ -18,6 +18,7 @@ IF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
TestTreeRingView.cxx
TestIcicleView.cxx
TestConeLayoutStrategy.cxx
TestSpanTreeLayoutStrategy.cxx
)
IF (VTK_USE_QT)
# add tests that require Qt
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestSpanTreeLayoutStrategy.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2008 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkSpanTreeLayoutStrategy.h"
#include "vtkGraphLayoutView.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTestUtilities.h"
#include "vtkXGMLReader.h"
using vtkstd::string;
#include "vtkSmartPointer.h"
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
int TestSpanTreeLayoutStrategy(int argc, char* argv[])
{
VTK_CREATE(vtkTesting, testHelper);
testHelper->AddArguments(argc,const_cast<const char **>(argv));
string dataRoot = testHelper->GetDataRoot();
string file = dataRoot + "/Data/Infovis/fsm.gml";
VTK_CREATE(vtkXGMLReader, reader);
reader->SetFileName(file.c_str());
reader->Update();
// Graph layout view
VTK_CREATE(vtkGraphLayoutView, view);
// VTK_CREATE(vtkSpanTreeLayoutStrategy, strategy);
// strategy->DepthFirstSpanningTreeOn();
// view->SetLayoutStrategy(strategy);
view->SetLayoutStrategyToSpanTree();
view->SetVertexLabelArrayName("vertex id");
view->VertexLabelVisibilityOn();
view->SetVertexColorArrayName("vertex id");
view->SetColorVertices(true);
// view->SetEdgeColorArrayName("distance");
// view->ColorEdgesOn();
// view->SetEdgeLabelArrayName("edge label");
// view->EdgeLabelVisibilityOn();
view->SetRepresentationFromInputConnection(reader->GetOutputPort());
view->GetRenderer()->ResetCamera();
VTK_CREATE(vtkRenderWindow, win);
win->SetSize( 600, 600 );
win->SetMultiSamples(0); // ensure to have the same test image everywhere
view->SetupRenderWindow(win);
view->SetInteractionModeTo3D();
view->SetLabelPlacementModeToLabelPlacer();
view->Update();
int retVal = vtkRegressionTestImage(win);
if( retVal == vtkRegressionTester::DO_INTERACTOR )
{
win->GetInteractor()->Initialize();
win->GetInteractor()->Start();
retVal = vtkRegressionTester::PASSED;
}
return !retVal;
}
......@@ -149,6 +149,7 @@ public:
// - "Pass Through" Use locations assigned to the input.
// - "Circular" Places vertices uniformly on a circle.
// - "Cone" Cone tree layout.
// - "Span Tree" Span Tree Layout.
// Default is "Simple 2D".
void SetLayoutStrategy(const char* name);
void SetLayoutStrategyToRandom()
......@@ -173,6 +174,8 @@ public:
{ this->SetLayoutStrategy("Cosmic Tree"); }
void SetLayoutStrategyToCone()
{ this->SetLayoutStrategy("Cone"); }
void SetLayoutStrategyToSpanTree()
{ this->SetLayoutStrategy("Span Tree"); }
const char* GetLayoutStrategyName();
// Description:
......
......@@ -65,6 +65,7 @@
#include "vtkSelectionNode.h"
#include "vtkSimple2DLayoutStrategy.h"
#include "vtkSmartPointer.h"
#include "vtkSpanTreeLayoutStrategy.h"
#include "vtkSphereSource.h"
#include "vtkTable.h"
#include "vtkTextProperty.h"
......@@ -74,7 +75,7 @@
#include <vtkstd/algorithm>
vtkCxxRevisionMacro(vtkRenderedGraphRepresentation, "1.5");
vtkCxxRevisionMacro(vtkRenderedGraphRepresentation, "1.6");
vtkStandardNewMacro(vtkRenderedGraphRepresentation);
vtkRenderedGraphRepresentation::vtkRenderedGraphRepresentation()
......@@ -748,6 +749,10 @@ void vtkRenderedGraphRepresentation::SetLayoutStrategy(vtkGraphLayoutStrategy* s
{
this->SetLayoutStrategyName("Cone");
}
else if (vtkSpanTreeLayoutStrategy::SafeDownCast(s))
{
this->SetLayoutStrategyName("Span Tree");
}
else
{
this->SetLayoutStrategyName("Unknown");
......@@ -807,6 +812,10 @@ void vtkRenderedGraphRepresentation::SetLayoutStrategy(const char* name)
{
strategy = vtkSmartPointer<vtkConeLayoutStrategy>::New();
}
else if (str == "spantree")
{
strategy = vtkSmartPointer<vtkSpanTreeLayoutStrategy>::New();
}
else if (str != "passthrough")
{
vtkErrorMacro("Unknown layout strategy: \"" << name << "\"");
......
......@@ -173,6 +173,8 @@ public:
{ this->SetLayoutStrategy("Cosmic Tree"); }
void SetLayoutStrategyToCone()
{ this->SetLayoutStrategy("Cone"); }
void SetLayoutStrategyToSpanTree()
{ this->SetLayoutStrategy("Span Tree"); }
// Description:
// Set the layout strategy to use coordinates from arrays.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment