PageRenderTime 125ms CodeModel.GetById 40ms app.highlight 60ms RepoModel.GetById 20ms app.codeStats 1ms

/Infovis/Testing/Cxx/TestGraphHierarchicalBundle.cxx

https://github.com/wschroed/VTK
C++ | 408 lines | 337 code | 37 blank | 34 comment | 42 complexity | 187914632b0ed0e443aeb500136b663b MD5 | raw file
  1/*=========================================================================
  2
  3  Program:   Visualization Toolkit
  4  Module:    $RCSfile$
  5
  6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  7  All rights reserved.
  8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  9
 10     This software is distributed WITHOUT ANY WARRANTY; without even
 11     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 12     PURPOSE.  See the above copyright notice for more information.
 13
 14=========================================================================*/
 15/*-------------------------------------------------------------------------
 16  Copyright 2008 Sandia Corporation.
 17  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 18  the U.S. Government retains certain rights in this software.
 19-------------------------------------------------------------------------*/
 20
 21#include "vtkActor.h"
 22#include "vtkActor2D.h"
 23#include "vtkCommand.h"
 24#include "vtkGraph.h"
 25#include "vtkGraphHierarchicalBundle.h"
 26#include "vtkGraphLayout.h"
 27#include "vtkGraphToPolyData.h"
 28#include "vtkInteractorStyleImage.h"
 29#include "vtkLookupTable.h"
 30#include "vtkMath.h"
 31#include "vtkMutableDirectedGraph.h"
 32#include "vtkPointData.h"
 33#include "vtkPoints.h"
 34#include "vtkPolyDataMapper.h"
 35#include "vtkProperty.h"
 36#include "vtkRandomGraphSource.h"
 37#include "vtkRegressionTestImage.h"
 38#include "vtkRenderer.h"
 39#include "vtkRenderWindow.h"
 40#include "vtkRenderWindowInteractor.h"
 41#include "vtkSmartPointer.h"
 42#include "vtkSplineFilter.h"
 43#include "vtkStringArray.h"
 44#include "vtkTextProperty.h"
 45#include "vtkTree.h"
 46#include "vtkTreeLayoutStrategy.h"
 47#include "vtkVariant.h"
 48//#include "vtkXMLTreeReader.h"
 49
 50#define VTK_CREATE(type, name) \
 51  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
 52
 53
 54#define RANDOM_TREE       0
 55#define STRUCTURED_TREE   1
 56#define VTK_SOURCES_TREE  2
 57
 58int TestGraphHierarchicalBundle(int argc, char* argv[])
 59{
 60  int treeType = STRUCTURED_TREE;
 61  const char* file = 0;
 62  bool showTree = false;
 63  vtkIdType numVertices = 200;
 64  vtkIdType numEdges = 100;
 65  double bundlingStrength = 0.9;
 66  bool radial = true;
 67  double angle = 360;
 68  double logSpacing = 0.8;
 69  double leafSpacing = 0.9;
 70
 71  for (int i = 1; i < argc; i++)
 72    {
 73    if (!strcmp(argv[i], "-I")) 
 74      {
 75      continue;
 76      }
 77    if (!strcmp(argv[i], "-D")) 
 78      {
 79      i++;
 80      continue;
 81      }
 82    if (!strcmp(argv[i], "-T")) 
 83      {
 84      i++;
 85      continue;
 86      }
 87    if (!strcmp(argv[i], "-V")) 
 88      {
 89      i++;
 90      continue;
 91      }
 92    if (!strcmp(argv[i], "-t")) 
 93      {
 94      showTree = true;
 95      continue;
 96      }
 97    if (!strcmp(argv[i], "-S")) 
 98      {
 99      radial = false;
100      continue;
101      }
102    if (!strcmp(argv[i], "-A")) 
103      {
104      i++;
105      angle = atof(argv[i]);
106      continue;
107      }
108    if (!strcmp(argv[i], "-L"))
109      {
110      i++;
111      logSpacing = atof(argv[i]);
112      continue;
113      }
114    if (!strcmp(argv[i], "-f"))
115      {
116      i++;
117      leafSpacing = atof(argv[i]);
118      continue;
119      }
120    if (!strcmp(argv[i], "-r"))
121      {
122      treeType = RANDOM_TREE;
123      i++;
124      numVertices = atoi(argv[i]);
125      i++;
126      numEdges = atoi(argv[i]);
127      continue;
128      }
129    if (!strcmp(argv[i], "-s"))
130      {
131      treeType = STRUCTURED_TREE;
132      i++;
133      numVertices = atoi(argv[i]);
134      i++;
135      numEdges = atoi(argv[i]);
136      continue;
137      }
138    if (!strcmp(argv[i], "-v"))
139      {
140      treeType = VTK_SOURCES_TREE;
141      i++;
142      file = argv[i];
143      continue;
144      }
145    if (!strcmp(argv[i], "-b"))
146      {
147      i++;
148      bundlingStrength = atof(argv[i]);
149      continue;
150      }
151
152    cerr << argv[0] << " Options:\n" 
153      << " -I : interactive\n"
154      << " -r #vertices #edges: show random tree with random edges\n"
155      << " -s #vertices #edges: show structured tree with structured edges\n"
156      //<< " -v filename : show VTK data in XML file\n"
157      << " -b strength : bundling strength (0.0 to 1.0; default 0.8)\n"
158      << " -S : standard tree layout (default radial)\n"
159      << " -A angle : tree sweep angle (default 360)\n"
160      << " -L logspacing : tree logspacing (0.0 to 1.0; default 0.8)\n"
161      << " -f leafspacing : tree leaf spacing\n"
162      << " -t : show tree instead of edge bundles\n";
163    return 0;
164    }
165  vtkIdType levelOneVertices = static_cast<vtkIdType>(sqrt(static_cast<float>(numVertices)));
166
167  // Create the graph.
168  
169  vtkGraph *graph = 0;
170  if (treeType == RANDOM_TREE)
171    {
172    VTK_CREATE(vtkRandomGraphSource, source);
173    source->SetNumberOfVertices(numVertices);
174    source->SetNumberOfEdges(numEdges);
175    source->SetStartWithTree(false);
176    source->Update();
177    graph = source->GetOutput();
178
179    VTK_CREATE(vtkStringArray, nameArray);
180    nameArray->SetName("name");
181    for (vtkIdType i = 0; i < graph->GetNumberOfVertices(); i++)
182      {
183      nameArray->InsertNextValue(vtkVariant(i).ToString());
184      }
185    graph->GetVertexData()->AddArray(nameArray);
186    graph->Register(0);
187    }
188  else if (treeType == STRUCTURED_TREE)
189    {
190    vtkMutableDirectedGraph* g = vtkMutableDirectedGraph::New();
191    for (vtkIdType v = 0; v < numVertices; v++)
192      {
193      g->AddVertex();
194      }
195    for (vtkIdType e = 0; e < numEdges; e++)
196      {
197      g->AddEdge(e%numVertices, (e*e)%numVertices);
198      }
199    graph = g;
200    }
201#if 0
202  else
203    {
204    VTK_CREATE(vtkXMLTreeReader, reader);
205    reader->SetFileName(file);
206    reader->Update();
207    graph = reader->GetOutput();
208    graph->Register(0);
209    }
210#endif
211
212  //for (vtkIdType a = 0; a < graph->GetNumberOfEdges(); a++)
213  //  {
214  //  cerr << "edge " << a << ": " << graph->GetSourceVertex(a) << "," << graph->GetTargetVertex(a) << endl;
215  //  }
216
217  // Create the tree.
218  VTK_CREATE(vtkMutableDirectedGraph, tree);
219  if (treeType == RANDOM_TREE)
220    {
221    tree->AddVertex();
222    for (vtkIdType i = 1; i < numVertices; i++)
223      {
224      vtkIdType parent = static_cast<vtkIdType>(vtkMath::Random(0, tree->GetNumberOfVertices()));
225      tree->AddChild(parent);
226      }
227    tree->GetVertexData()->AddArray(graph->GetVertexData()->GetAbstractArray("name"));
228    }
229  else if (treeType == STRUCTURED_TREE)
230    {
231    vtkIdType i;
232    tree->AddVertex();
233    for (i = 0; i < levelOneVertices; i++)
234      {
235      tree->AddChild(0);
236      }
237    vtkIdType levelTwoVertices = numVertices - levelOneVertices - 1;
238    for (i = 0; i < levelTwoVertices; i++)
239      {
240      tree->AddChild(static_cast<vtkIdType>(i / (levelTwoVertices / static_cast<double>(levelOneVertices)) + 1.5));
241      }
242    tree->GetVertexData()->AddArray(graph->GetVertexData()->GetAbstractArray("name"));
243    }
244  else
245    {
246    VTK_CREATE(vtkStringArray, kitNames);
247    kitNames->InsertNextValue("Common");
248    kitNames->InsertNextValue("Filtering");
249    kitNames->InsertNextValue("GenericFiltering");
250    kitNames->InsertNextValue("Graphics");
251    kitNames->InsertNextValue("Hybrid");
252    kitNames->InsertNextValue("Imaging");
253    kitNames->InsertNextValue("Infovis");
254    kitNames->InsertNextValue("IO");
255    kitNames->InsertNextValue("Parallel");
256    kitNames->InsertNextValue("Rendering");
257    kitNames->InsertNextValue("VolumeRendering");
258    kitNames->InsertNextValue("Widgets");
259
260    // Add vertices representing classes.
261    for (vtkIdType i = 0; i < graph->GetNumberOfVertices(); i++)
262      {
263      tree->AddVertex();
264      }
265
266    VTK_CREATE(vtkStringArray, extendedNameArray);
267    extendedNameArray->DeepCopy(graph->GetVertexData()->GetAbstractArray("name"));
268    extendedNameArray->SetName("name");
269
270    // Add root.
271    extendedNameArray->InsertNextValue("VTK");
272    vtkIdType root = tree->AddVertex();
273
274    // Add kit vertices.
275    for (vtkIdType k = 0; k < kitNames->GetNumberOfValues(); k++)
276      {
277      tree->AddChild(root);
278      extendedNameArray->InsertNextValue(kitNames->GetValue(k));
279      }
280
281    vtkStringArray* fileArray = vtkStringArray::SafeDownCast(
282      graph->GetVertexData()->GetAbstractArray("filename"));
283    for (vtkIdType i = 0; i < graph->GetNumberOfVertices(); i++)
284      {
285      vtkStdString curFile = fileArray->GetValue(i);
286      bool found = false;
287      vtkIdType k;
288      for (k = 0; k < kitNames->GetNumberOfValues(); k++)
289        {
290        vtkStdString kit = kitNames->GetValue(k);
291        if (curFile.substr(0, kit.length()) == kit)
292          {
293          tree->AddEdge(root + 1 + k, i);
294          found = true;
295          break;
296          }
297        }
298      if (!found)
299        {
300        cerr << "cannot find match for filename " << file << endl;
301        }
302      }
303
304    tree->GetVertexData()->AddArray(extendedNameArray);
305    }
306
307  VTK_CREATE(vtkTree, realTree);
308  if (!realTree->CheckedShallowCopy(tree))
309    {
310    cerr << "Invalid tree structure." << endl;
311    }
312
313  VTK_CREATE(vtkTreeLayoutStrategy, treeStrategy);
314  treeStrategy->SetAngle(angle);
315  treeStrategy->SetRadial(radial);
316  treeStrategy->SetLogSpacingValue(logSpacing);
317  treeStrategy->SetLeafSpacing(leafSpacing);
318
319  VTK_CREATE(vtkGraphLayout, treeLayout);
320  treeLayout->SetInput(realTree);
321  treeLayout->SetLayoutStrategy(treeStrategy);
322
323  VTK_CREATE(vtkGraphHierarchicalBundle, bundle);
324  bundle->SetInput(0, graph);
325  bundle->SetInputConnection(1, treeLayout->GetOutputPort(0));
326  bundle->SetBundlingStrength(bundlingStrength);
327  bundle->SetDirectMapping(true);
328
329  VTK_CREATE(vtkSplineFilter, spline);
330  spline->SetInputConnection(0, bundle->GetOutputPort(0));
331
332  VTK_CREATE(vtkLookupTable, lut);
333  int numValues = 100;
334  lut->SetNumberOfTableValues(numValues);
335  lut->Build();
336  for (int i = 0; i < numValues; i++)
337    {
338    double frac = static_cast<double>(i)/numValues;
339    lut->SetTableValue(i, 1.0 - frac, frac, 0.0);
340    }
341
342  VTK_CREATE(vtkPolyDataMapper, polyMapper);
343  polyMapper->SetInputConnection(0, spline->GetOutputPort(0));
344  polyMapper->SetScalarModeToUsePointFieldData();
345  polyMapper->SetLookupTable(lut);
346  polyMapper->SelectColorArray("fraction");
347
348  VTK_CREATE(vtkActor, polyActor);
349  polyActor->SetMapper(polyMapper);
350  polyActor->GetProperty()->SetOpacity(0.5);
351
352  VTK_CREATE(vtkGraphToPolyData, treePoly);
353  //treePoly->SetInput(tree);
354  treePoly->SetInputConnection(0, treeLayout->GetOutputPort(0));
355
356  VTK_CREATE(vtkPolyDataMapper, treeMapper);
357  treeMapper->SetInputConnection(0, treePoly->GetOutputPort(0));
358
359  VTK_CREATE(vtkActor, treeActor);
360  treeActor->SetMapper(treeMapper);
361  treeActor->GetProperty()->SetColor(0.4, 0.6, 1.0);
362
363#if 0
364  VTK_CREATE(vtkDynamic2DLabelMapper, labelMapper);
365  labelMapper->SetInputConnection(0, treePoly->GetOutputPort(0));
366  labelMapper->SetLabelModeToLabelFieldData();
367  labelMapper->SetFieldDataName("name");
368  labelMapper->SetLabelFormat("%s");
369  labelMapper->GetLabelTextProperty()->SetColor(0.0, 0.0, 0.0);
370
371  VTK_CREATE(vtkActor2D, labelActor);
372  labelActor->SetMapper(labelMapper);
373#endif
374
375  VTK_CREATE(vtkRenderer, ren);
376  ren->SetBackground(1.0, 1.0, 1.0);
377
378  if (showTree)
379    {
380    ren->AddActor(treeActor);
381    }
382  else
383    {
384    ren->AddActor(polyActor);
385    }
386  //ren->AddActor2D(labelActor);
387  
388  VTK_CREATE(vtkRenderWindowInteractor, iren);
389  VTK_CREATE(vtkInteractorStyleImage, style);
390  VTK_CREATE(vtkRenderWindow, win);
391  iren->SetInteractorStyle(style);
392  win->AddRenderer(ren);
393  win->SetInteractor(iren);
394  //win->LineSmoothingOn();
395
396  int retVal = vtkRegressionTestImage(win);
397  if (retVal == vtkRegressionTester::DO_INTERACTOR)
398    {
399    win->Render();
400    iren->Start();
401    retVal = vtkRegressionTester::PASSED;
402    }
403
404  // Clean up
405  graph->Delete();
406
407  return !retVal;
408}