PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

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