vtkRenderedGraphRepresentation.cxx 47.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRenderedGraphRepresentation.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 "vtkRenderedGraphRepresentation.h"

#include "vtkAbstractTransform.h"
#include "vtkActor.h"
#include "vtkAlgorithmOutput.h"
#include "vtkAnnotationLink.h"
#include "vtkApplyColors.h"
28
#include "vtkApplyIcons.h"
29 30 31 32 33 34
#include "vtkArcParallelEdgeStrategy.h"
#include "vtkAssignCoordinatesLayoutStrategy.h"
#include "vtkCellData.h"
#include "vtkCircularLayoutStrategy.h"
#include "vtkClustering2DLayoutStrategy.h"
#include "vtkCommunity2DLayoutStrategy.h"
35
#include "vtkConeLayoutStrategy.h"
36 37 38 39 40 41 42 43 44 45 46 47
#include "vtkConvertSelection.h"
#include "vtkCosmicTreeLayoutStrategy.h"
#include "vtkDirectedGraph.h"
#include "vtkEdgeCenters.h"
#include "vtkEdgeLayout.h"
#include "vtkFast2DLayoutStrategy.h"
#include "vtkForceDirectedLayoutStrategy.h"
#include "vtkGeoEdgeStrategy.h"
#include "vtkGraphLayout.h"
#include "vtkGraphToGlyphs.h"
#include "vtkGraphToPoints.h"
#include "vtkGraphToPolyData.h"
48
#include "vtkIconGlyphFilter.h"
49
#include "vtkIdTypeArray.h"
50
#include "vtkImageData.h"
51 52 53 54 55 56
#include "vtkInformation.h"
#include "vtkLookupTable.h"
#include "vtkObjectFactory.h"
#include "vtkPassThroughEdgeStrategy.h"
#include "vtkPassThroughLayoutStrategy.h"
#include "vtkPerturbCoincidentVertices.h"
57
#include "vtkPointSetToLabelHierarchy.h"
58 59
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
60
#include "vtkPolyDataMapper2D.h"
61 62
#include "vtkProperty.h"
#include "vtkRandomLayoutStrategy.h"
63
#include "vtkRemoveHiddenData.h"
64 65 66 67 68 69 70 71 72
#include "vtkRenderer.h"
#include "vtkRenderView.h"
#include "vtkRenderWindow.h"
#include "vtkScalarBarActor.h"
#include "vtkScalarBarWidget.h"
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
#include "vtkSimple2DLayoutStrategy.h"
#include "vtkSmartPointer.h"
73
#include "vtkSpanTreeLayoutStrategy.h"
74 75 76
#include "vtkSphereSource.h"
#include "vtkTable.h"
#include "vtkTextProperty.h"
77
#include "vtkTexture.h"
78 79
#include "vtkTexturedActor2D.h"
#include "vtkTransformCoordinateSystems.h"
80 81 82 83
#include "vtkTreeLayoutStrategy.h"
#include "vtkVertexDegree.h"
#include "vtkViewTheme.h"

84
#include <cctype>
85
#include <algorithm>
86

87 88


Dave Partyka's avatar
Dave Partyka committed
89

90 91 92 93 94 95 96 97 98
vtkStandardNewMacro(vtkRenderedGraphRepresentation);

vtkRenderedGraphRepresentation::vtkRenderedGraphRepresentation()
{
  this->ApplyColors         = vtkSmartPointer<vtkApplyColors>::New();
  this->VertexDegree        = vtkSmartPointer<vtkVertexDegree>::New();
  this->EmptyPolyData       = vtkSmartPointer<vtkPolyData>::New();
  this->EdgeCenters         = vtkSmartPointer<vtkEdgeCenters>::New();
  this->GraphToPoints       = vtkSmartPointer<vtkGraphToPoints>::New();
99 100
  this->VertexLabelHierarchy = vtkSmartPointer<vtkPointSetToLabelHierarchy>::New();
  this->EdgeLabelHierarchy  = vtkSmartPointer<vtkPointSetToLabelHierarchy>::New();
101 102 103 104 105 106 107 108 109 110 111 112 113 114
  this->Layout              = vtkSmartPointer<vtkGraphLayout>::New();
  this->Coincident          = vtkSmartPointer<vtkPerturbCoincidentVertices>::New();
  this->EdgeLayout          = vtkSmartPointer<vtkEdgeLayout>::New();
  this->GraphToPoly         = vtkSmartPointer<vtkGraphToPolyData>::New();
  this->EdgeMapper          = vtkSmartPointer<vtkPolyDataMapper>::New();
  this->EdgeActor           = vtkSmartPointer<vtkActor>::New();
  this->VertexGlyph         = vtkSmartPointer<vtkGraphToGlyphs>::New();
  this->VertexMapper        = vtkSmartPointer<vtkPolyDataMapper>::New();
  this->VertexActor         = vtkSmartPointer<vtkActor>::New();
  this->OutlineGlyph        = vtkSmartPointer<vtkGraphToGlyphs>::New();
  this->OutlineMapper       = vtkSmartPointer<vtkPolyDataMapper>::New();
  this->OutlineActor        = vtkSmartPointer<vtkActor>::New();
  this->VertexScalarBar     = vtkSmartPointer<vtkScalarBarWidget>::New();
  this->EdgeScalarBar       = vtkSmartPointer<vtkScalarBarWidget>::New();
115
  this->RemoveHiddenGraph   = vtkSmartPointer<vtkRemoveHiddenData>::New();
116 117 118 119 120 121
  this->ApplyVertexIcons    = vtkSmartPointer<vtkApplyIcons>::New();
  this->VertexIconPoints    = vtkSmartPointer<vtkGraphToPoints>::New();
  this->VertexIconTransform = vtkSmartPointer<vtkTransformCoordinateSystems>::New();
  this->VertexIconGlyph     = vtkSmartPointer<vtkIconGlyphFilter>::New();
  this->VertexIconMapper    = vtkSmartPointer<vtkPolyDataMapper2D>::New();
  this->VertexIconActor     = vtkSmartPointer<vtkTexturedActor2D>::New();
122

123 124 125 126 127 128 129
  this->VertexHoverArrayName = nullptr;
  this->EdgeHoverArrayName = nullptr;
  this->VertexColorArrayNameInternal = nullptr;
  this->EdgeColorArrayNameInternal = nullptr;
  this->ScalingArrayNameInternal = nullptr;
  this->LayoutStrategyName = nullptr;
  this->EdgeLayoutStrategyName = nullptr;
130

131 132 133
  this->HideVertexLabelsOnInteraction = false;
  this->HideEdgeLabelsOnInteraction = false;

134 135
  this->EdgeSelection = true;

136 137 138 139 140 141
  /*
   <graphviz>
   digraph {
     Layout -> Coincident -> EdgeLayout -> VertexDegree -> ApplyColors
     ApplyColors -> VertexGlyph -> VertexMapper -> VertexActor
     ApplyColors -> GraphToPoly -> EdgeMapper -> EdgeActor
142
     ApplyColors -> ApplyVertexIcons
143
     Coincident -> OutlineGlyph -> OutlineMapper -> OutlineActor
144

145
     VertexDegree -> GraphToPoints
146
     GraphToPoints -> VertexLabelHierarchy -> "vtkRenderView Labels"
147
     GraphToPoints -> VertexIcons -> VertexIconPriority -> "vtkRenderView Icons"
148
     ApplyVertexIcons -> VertexIconPoints -> VertexIconTransform -> VertexIconGlyphFilter -> VertexIconMapper -> VertexIconActor
149
     VertexDegree -> EdgeCenters
150
     EdgeCenters -> EdgeLabelHierarchy -> "vtkRenderView Labels"
151 152 153 154 155
     EdgeCenters -> EdgeIcons -> EdgeIconPriority -> "vtkRenderView Icons"
   }
   </graphviz>
  */

156 157 158
  this->Coincident->SetInputConnection(this->Layout->GetOutputPort());
  this->RemoveHiddenGraph->SetInputConnection(this->Coincident->GetOutputPort());
  this->EdgeLayout->SetInputConnection(this->RemoveHiddenGraph->GetOutputPort());
159 160
  this->VertexDegree->SetInputConnection(this->EdgeLayout->GetOutputPort());
  this->ApplyColors->SetInputConnection(this->VertexDegree->GetOutputPort());
161
  this->ApplyVertexIcons->SetInputConnection(this->ApplyColors->GetOutputPort());
162 163 164 165 166 167 168

  // Vertex actor
  this->VertexGlyph->SetInputConnection(this->ApplyColors->GetOutputPort());
  this->VertexMapper->SetInputConnection(this->VertexGlyph->GetOutputPort());
  this->VertexActor->SetMapper(this->VertexMapper);

  // Outline actor
169
  this->OutlineGlyph->SetInputConnection(this->RemoveHiddenGraph->GetOutputPort());
170 171 172 173 174 175 176 177
  this->OutlineMapper->SetInputConnection(this->OutlineGlyph->GetOutputPort());
  this->OutlineActor->SetMapper(this->OutlineMapper);

  // Edge actor
  this->GraphToPoly->SetInputConnection(this->ApplyColors->GetOutputPort());
  this->EdgeMapper->SetInputConnection(this->GraphToPoly->GetOutputPort());
  this->EdgeActor->SetMapper(this->EdgeMapper);

178 179 180 181 182 183 184 185 186 187 188 189
  // Experimental icons
  this->VertexIconPoints->SetInputConnection(this->ApplyVertexIcons->GetOutputPort());
  this->VertexIconTransform->SetInputConnection(this->VertexIconPoints->GetOutputPort());
  this->VertexIconGlyph->SetInputConnection(this->VertexIconTransform->GetOutputPort());
  this->VertexIconMapper->SetInputConnection(this->VertexIconGlyph->GetOutputPort());
  this->VertexIconActor->SetMapper(this->VertexIconMapper);
  this->VertexIconTransform->SetInputCoordinateSystemToWorld();
  this->VertexIconTransform->SetOutputCoordinateSystemToDisplay();
  this->VertexIconGlyph->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "vtkApplyIcons icon");
  this->ApplyVertexIcons->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_VERTICES, "icon");
  this->VertexIconActor->VisibilityOff();

190 191
  this->GraphToPoints->SetInputConnection(this->VertexDegree->GetOutputPort());
  this->EdgeCenters->SetInputConnection(this->VertexDegree->GetOutputPort());
192 193
  this->EdgeLabelHierarchy->SetInputData(this->EmptyPolyData);
  this->VertexLabelHierarchy->SetInputData(this->EmptyPolyData);
194 195 196 197

  // Set default parameters
  vtkSmartPointer<vtkDirectedGraph> g =
    vtkSmartPointer<vtkDirectedGraph>::New();
198
  this->Layout->SetInputData(g);
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
  vtkSmartPointer<vtkFast2DLayoutStrategy> strategy =
    vtkSmartPointer<vtkFast2DLayoutStrategy>::New();
  this->Layout->SetLayoutStrategy(strategy);
  //this->Layout->SetZRange(0.001);
  this->Layout->SetZRange(0.0);
  vtkSmartPointer<vtkArcParallelEdgeStrategy> edgeStrategy =
    vtkSmartPointer<vtkArcParallelEdgeStrategy>::New();
  this->Layout->UseTransformOn();
  this->SetVertexColorArrayName("VertexDegree");
  this->SetVertexLabelArrayName("VertexDegree");
  this->SetVertexLabelPriorityArrayName("VertexDegree");
  this->SetVertexIconArrayName("IconIndex");
  this->SetVertexIconPriorityArrayName("VertexDegree");
  this->EdgeLayout->SetLayoutStrategy(edgeStrategy);

  this->VertexGlyph->FilledOn();
  this->VertexGlyph->SetGlyphType(vtkGraphToGlyphs::VERTEX);
  this->VertexMapper->SetScalarModeToUseCellFieldData();
  this->VertexMapper->SelectColorArray("vtkApplyColors color");
  this->VertexMapper->SetScalarVisibility(true);

  this->OutlineGlyph->FilledOff();
  this->OutlineGlyph->SetGlyphType(vtkGraphToGlyphs::VERTEX);
  this->OutlineMapper->SetScalarVisibility(false);
  this->OutlineActor->PickableOff();
  this->OutlineActor->GetProperty()->FrontfaceCullingOn();

  this->EdgeMapper->SetScalarModeToUseCellFieldData();
  this->EdgeMapper->SelectColorArray("vtkApplyColors color");
  this->EdgeMapper->SetScalarVisibility(true);
  this->EdgeActor->SetPosition(0, 0, -0.003);

  this->VertexScalarBar->GetScalarBarActor()->VisibilityOff();
  this->EdgeScalarBar->GetScalarBarActor()->VisibilityOff();

  vtkSmartPointer<vtkViewTheme> theme =
    vtkSmartPointer<vtkViewTheme>::New();
  this->ApplyViewTheme(theme);
}

vtkRenderedGraphRepresentation::~vtkRenderedGraphRepresentation()
{
241 242 243 244 245 246 247
  this->SetScalingArrayNameInternal(nullptr);
  this->SetVertexColorArrayNameInternal(nullptr);
  this->SetEdgeColorArrayNameInternal(nullptr);
  this->SetLayoutStrategyName(nullptr);
  this->SetEdgeLayoutStrategyName(nullptr);
  this->SetVertexHoverArrayName(nullptr);
  this->SetEdgeHoverArrayName(nullptr);
248 249 250 251
}

void vtkRenderedGraphRepresentation::SetVertexLabelArrayName(const char* name)
{
252
  this->VertexLabelHierarchy->SetLabelArrayName(name);
253 254 255 256
}

void vtkRenderedGraphRepresentation::SetEdgeLabelArrayName(const char* name)
{
257
  this->EdgeLabelHierarchy->SetLabelArrayName(name);
258 259 260 261
}

const char* vtkRenderedGraphRepresentation::GetVertexLabelArrayName()
{
262
  return this->VertexLabelHierarchy->GetLabelArrayName();
263 264 265 266
}

const char* vtkRenderedGraphRepresentation::GetEdgeLabelArrayName()
{
267
  return this->EdgeLabelHierarchy->GetLabelArrayName();
268 269 270 271
}

void vtkRenderedGraphRepresentation::SetVertexLabelPriorityArrayName(const char* name)
{
272
  this->VertexLabelHierarchy->SetPriorityArrayName(name);
273 274 275 276
}

void vtkRenderedGraphRepresentation::SetEdgeLabelPriorityArrayName(const char* name)
{
277
  this->EdgeLabelHierarchy->SetPriorityArrayName(name);
278 279 280 281
}

const char* vtkRenderedGraphRepresentation::GetVertexLabelPriorityArrayName()
{
282
  return this->VertexLabelHierarchy->GetPriorityArrayName();
283 284 285 286
}

const char* vtkRenderedGraphRepresentation::GetEdgeLabelPriorityArrayName()
{
287
  return this->EdgeLabelHierarchy->GetPriorityArrayName();
288 289 290 291 292
}

void vtkRenderedGraphRepresentation::SetVertexLabelVisibility(bool b)
{
  if (b)
293
  {
294
    this->VertexLabelHierarchy->SetInputConnection(this->GraphToPoints->GetOutputPort());
295
  }
296
  else
297
  {
298
    this->VertexLabelHierarchy->SetInputData(this->EmptyPolyData);
299
  }
300 301 302 303 304
}

void vtkRenderedGraphRepresentation::SetEdgeLabelVisibility(bool b)
{
  if (b)
305
  {
306
    this->EdgeLabelHierarchy->SetInputConnection(this->EdgeCenters->GetOutputPort());
307
  }
308
  else
309
  {
310
    this->EdgeLabelHierarchy->SetInputData(this->EmptyPolyData);
311
  }
312 313 314 315
}

bool vtkRenderedGraphRepresentation::GetVertexLabelVisibility()
{
316
  return this->VertexLabelHierarchy->GetInputConnection(0, 0) ==
317 318 319 320 321
         this->GraphToPoints->GetOutputPort();
}

bool vtkRenderedGraphRepresentation::GetEdgeLabelVisibility()
{
322
  return this->EdgeLabelHierarchy->GetInputConnection(0, 0) ==
323 324 325 326 327 328 329 330 331 332 333 334 335
         this->EdgeCenters->GetOutputPort();
}

void vtkRenderedGraphRepresentation::SetEdgeVisibility(bool b)
{
  this->EdgeActor->SetVisibility(b);
}

bool vtkRenderedGraphRepresentation::GetEdgeVisibility()
{
  return this->EdgeActor->GetVisibility() ? true : false;
}

336 337 338 339 340 341 342 343 344 345
void vtkRenderedGraphRepresentation::SetEdgeSelection(bool b)
{
  this->EdgeSelection = b;
}

bool vtkRenderedGraphRepresentation::GetEdgeSelection()
{
  return this->EdgeSelection;
}

346 347
void vtkRenderedGraphRepresentation::SetVertexLabelTextProperty(vtkTextProperty* p)
{
348
  this->VertexLabelHierarchy->SetTextProperty(p);
349 350 351 352
}

void vtkRenderedGraphRepresentation::SetEdgeLabelTextProperty(vtkTextProperty* p)
{
353
  this->EdgeLabelHierarchy->SetTextProperty(p);
354 355 356 357
}

vtkTextProperty* vtkRenderedGraphRepresentation::GetVertexLabelTextProperty()
{
358
  return this->VertexLabelHierarchy->GetTextProperty();
359 360 361 362
}

vtkTextProperty* vtkRenderedGraphRepresentation::GetEdgeLabelTextProperty()
{
363
  return this->EdgeLabelHierarchy->GetTextProperty();
364 365 366 367
}

void vtkRenderedGraphRepresentation::SetVertexIconArrayName(const char* name)
{
368
  this->ApplyVertexIcons->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_VERTICES, name);
369 370
}

Jeff Baumes's avatar
Jeff Baumes committed
371
void vtkRenderedGraphRepresentation::SetEdgeIconArrayName(const char*)
372
{
373
  // TODO: Implement.
374 375 376 377
}

const char* vtkRenderedGraphRepresentation::GetVertexIconArrayName()
{
378
  // TODO: Implement.
379
  return nullptr;
380 381 382 383
}

const char* vtkRenderedGraphRepresentation::GetEdgeIconArrayName()
{
384
  // TODO: Implement.
385
  return nullptr;
386 387
}

Jeff Baumes's avatar
Jeff Baumes committed
388
void vtkRenderedGraphRepresentation::SetVertexIconPriorityArrayName(const char*)
389
{
390
  // TODO: Implement.
391 392
}

Jeff Baumes's avatar
Jeff Baumes committed
393
void vtkRenderedGraphRepresentation::SetEdgeIconPriorityArrayName(const char*)
394
{
395
  // TODO: Implement.
396 397 398 399
}

const char* vtkRenderedGraphRepresentation::GetVertexIconPriorityArrayName()
{
400
  // TODO: Implement.
401
  return nullptr;
402 403 404 405
}

const char* vtkRenderedGraphRepresentation::GetEdgeIconPriorityArrayName()
{
406
  // TODO: Implement.
407
  return nullptr;
408 409 410 411
}

void vtkRenderedGraphRepresentation::SetVertexIconVisibility(bool b)
{
412
  this->VertexIconActor->SetVisibility(b);
413 414
}

Jeff Baumes's avatar
Jeff Baumes committed
415
void vtkRenderedGraphRepresentation::SetEdgeIconVisibility(bool)
416
{
417
  // TODO: Implement.
418 419 420 421
}

bool vtkRenderedGraphRepresentation::GetVertexIconVisibility()
{
422
  return (this->VertexIconActor->GetVisibility() ? true : false);
423 424 425 426
}

bool vtkRenderedGraphRepresentation::GetEdgeIconVisibility()
{
427 428
  // TODO: Implement.
  return false;
429 430 431 432
}

void vtkRenderedGraphRepresentation::AddVertexIconType(const char* name, int type)
{
433 434
  this->ApplyVertexIcons->SetIconType(name, type);
  this->ApplyVertexIcons->UseLookupTableOn();
435
}
436

Jeff Baumes's avatar
Jeff Baumes committed
437
void vtkRenderedGraphRepresentation::AddEdgeIconType(const char*, int)
438
{
439
  // TODO: Implement.
440 441 442 443
}

void vtkRenderedGraphRepresentation::ClearVertexIconTypes()
{
444 445
  this->ApplyVertexIcons->ClearAllIconTypes();
  this->ApplyVertexIcons->UseLookupTableOff();
446 447 448 449
}

void vtkRenderedGraphRepresentation::ClearEdgeIconTypes()
{
450
  // TODO: Implement.
451 452 453 454
}

void vtkRenderedGraphRepresentation::SetUseVertexIconTypeMap(bool b)
{
455
  this->ApplyVertexIcons->SetUseLookupTable(b);
456 457
}

Jeff Baumes's avatar
Jeff Baumes committed
458
void vtkRenderedGraphRepresentation::SetUseEdgeIconTypeMap(bool)
459
{
460
  // TODO: Implement.
461 462 463 464
}

bool vtkRenderedGraphRepresentation::GetUseVertexIconTypeMap()
{
465
  return this->ApplyVertexIcons->GetUseLookupTable();
466 467 468 469
}

bool vtkRenderedGraphRepresentation::GetUseEdgeIconTypeMap()
{
470 471
  // TODO: Implement.
  return false;
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
}

// TODO: Icon alignment
void vtkRenderedGraphRepresentation::SetVertexIconAlignment(int align)
{
  (void)align;
}

int vtkRenderedGraphRepresentation::GetVertexIconAlignment()
{
  return 0;
}

void vtkRenderedGraphRepresentation::SetEdgeIconAlignment(int align)
{
  (void)align;
}

int vtkRenderedGraphRepresentation::GetEdgeIconAlignment()
{
  return 0;
}

495 496 497 498 499 500 501 502 503 504
void vtkRenderedGraphRepresentation::SetVertexSelectedIcon(int icon)
{
  this->ApplyVertexIcons->SetSelectedIcon(icon);
}

int vtkRenderedGraphRepresentation::GetVertexSelectedIcon()
{
  return this->ApplyVertexIcons->GetSelectedIcon();
}

505 506 507 508 509 510 511 512 513 514
void vtkRenderedGraphRepresentation::SetVertexDefaultIcon(int icon)
{
  this->ApplyVertexIcons->SetDefaultIcon(icon);
}

int vtkRenderedGraphRepresentation::GetVertexDefaultIcon()
{
  return this->ApplyVertexIcons->GetDefaultIcon();
}

515 516 517 518 519 520 521 522 523 524
void vtkRenderedGraphRepresentation::SetVertexIconSelectionMode(int mode)
{
  this->ApplyVertexIcons->SetSelectionMode(mode);
}

int vtkRenderedGraphRepresentation::GetVertexIconSelectionMode()
{
  return this->ApplyVertexIcons->GetSelectionMode();
}

525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
void vtkRenderedGraphRepresentation::SetColorVerticesByArray(bool b)
{
  this->ApplyColors->SetUsePointLookupTable(b);
}

bool vtkRenderedGraphRepresentation::GetColorVerticesByArray()
{
  return this->ApplyColors->GetUsePointLookupTable();
}

void vtkRenderedGraphRepresentation::SetVertexColorArrayName(const char* name)
{
  this->SetVertexColorArrayNameInternal(name);
  this->ApplyColors->SetInputArrayToProcess(0, 0, 0,
    vtkDataObject::FIELD_ASSOCIATION_VERTICES, name);
540
  this->VertexScalarBar->GetScalarBarActor()->SetTitle(name);
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
}

const char* vtkRenderedGraphRepresentation::GetVertexColorArrayName()
{
  return this->GetVertexColorArrayNameInternal();
}

void vtkRenderedGraphRepresentation::SetColorEdgesByArray(bool b)
{
  this->ApplyColors->SetUseCellLookupTable(b);
}

bool vtkRenderedGraphRepresentation::GetColorEdgesByArray()
{
  return this->ApplyColors->GetUseCellLookupTable();
}

void vtkRenderedGraphRepresentation::SetEdgeColorArrayName(const char* name)
{
560
  this->SetEdgeColorArrayNameInternal(name);
561 562
  this->ApplyColors->SetInputArrayToProcess(1, 0, 0,
    vtkDataObject::FIELD_ASSOCIATION_EDGES, name);
563
  this->EdgeScalarBar->GetScalarBarActor()->SetTitle(name);
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
}

const char* vtkRenderedGraphRepresentation::GetEdgeColorArrayName()
{
  return this->GetEdgeColorArrayNameInternal();
}

// TODO: Implement enable stuff.
void vtkRenderedGraphRepresentation::SetEnableVerticesByArray(bool b)
{
  (void)b;
}

bool vtkRenderedGraphRepresentation::GetEnableVerticesByArray()
{
  return false;
}

void vtkRenderedGraphRepresentation::SetEnabledVerticesArrayName(const char* name)
{
  (void)name;
}

const char* vtkRenderedGraphRepresentation::GetEnabledVerticesArrayName()
{
589
  return nullptr;
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
}

void vtkRenderedGraphRepresentation::SetEnableEdgesByArray(bool b)
{
  (void)b;
}

bool vtkRenderedGraphRepresentation::GetEnableEdgesByArray()
{
  return false;
}

void vtkRenderedGraphRepresentation::SetEnabledEdgesArrayName(const char* name)
{
  (void)name;
}

const char* vtkRenderedGraphRepresentation::GetEnabledEdgesArrayName()
{
609
  return nullptr;
610 611 612 613 614
}

void vtkRenderedGraphRepresentation::SetGlyphType(int type)
{
  if (type != this->VertexGlyph->GetGlyphType())
615
  {
616 617 618
    this->VertexGlyph->SetGlyphType(type);
    this->OutlineGlyph->SetGlyphType(type);
    if (type == vtkGraphToGlyphs::SPHERE)
619
    {
620
      this->OutlineActor->GetProperty()->FrontfaceCullingOn();
621
    }
622
    else
623
    {
624 625
      this->OutlineActor->GetProperty()->FrontfaceCullingOff();
    }
626
  }
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
}

int vtkRenderedGraphRepresentation::GetGlyphType()
{
  return this->VertexGlyph->GetGlyphType();
}

void vtkRenderedGraphRepresentation::SetScaling(bool b)
{
  this->VertexGlyph->SetScaling(b);
  this->OutlineGlyph->SetScaling(b);
}

bool vtkRenderedGraphRepresentation::GetScaling()
{
  return this->VertexGlyph->GetScaling();
}

void vtkRenderedGraphRepresentation::SetScalingArrayName(const char* name)
{
  this->VertexGlyph->SetInputArrayToProcess(
    0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_VERTICES, name);
  this->OutlineGlyph->SetInputArrayToProcess(
    0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_VERTICES, name);
  this->SetScalingArrayNameInternal(name);
}

const char* vtkRenderedGraphRepresentation::GetScalingArrayName()
{
  return this->GetScalingArrayNameInternal();
}

void vtkRenderedGraphRepresentation::SetVertexScalarBarVisibility(bool b)
{
  this->VertexScalarBar->GetScalarBarActor()->SetVisibility(b);
}

bool vtkRenderedGraphRepresentation::GetVertexScalarBarVisibility()
{
  return this->VertexScalarBar->GetScalarBarActor()->GetVisibility() ? true : false;
}

void vtkRenderedGraphRepresentation::SetEdgeScalarBarVisibility(bool b)
{
  this->EdgeScalarBar->GetScalarBarActor()->SetVisibility(b);
}

bool vtkRenderedGraphRepresentation::GetEdgeScalarBarVisibility()
{
  return this->EdgeScalarBar->GetScalarBarActor()->GetVisibility() ? true : false;
}

679 680
vtkScalarBarWidget* vtkRenderedGraphRepresentation::GetVertexScalarBar()
{
681
  return this->VertexScalarBar;
682 683 684 685
}

vtkScalarBarWidget* vtkRenderedGraphRepresentation::GetEdgeScalarBar()
{
686
  return this->EdgeScalarBar;
687 688
}

689 690 691 692 693 694 695 696
bool vtkRenderedGraphRepresentation::IsLayoutComplete()
{
  return this->Layout->IsLayoutComplete() ? true : false;
}

void vtkRenderedGraphRepresentation::UpdateLayout()
{
  if (!this->IsLayoutComplete())
697
  {
698 699
    this->Layout->Modified();
    // TODO : Should render here??
700
  }
701 702 703 704 705
}

void vtkRenderedGraphRepresentation::SetLayoutStrategy(vtkGraphLayoutStrategy* s)
{
  if (!s)
706
  {
707
    vtkErrorMacro("Layout strategy must not be nullptr.");
708
    return;
709
  }
710
  if (vtkRandomLayoutStrategy::SafeDownCast(s))
711
  {
712
    this->SetLayoutStrategyName("Random");
713
  }
714
  else if (vtkForceDirectedLayoutStrategy::SafeDownCast(s))
715
  {
716
    this->SetLayoutStrategyName("Force Directed");
717
  }
718
  else if (vtkSimple2DLayoutStrategy::SafeDownCast(s))
719
  {
720
    this->SetLayoutStrategyName("Simple 2D");
721
  }
722
  else if (vtkClustering2DLayoutStrategy::SafeDownCast(s))
723
  {
724
    this->SetLayoutStrategyName("Clustering 2D");
725
  }
726
  else if (vtkCommunity2DLayoutStrategy::SafeDownCast(s))
727
  {
728
    this->SetLayoutStrategyName("Community 2D");
729
  }
730
  else if (vtkFast2DLayoutStrategy::SafeDownCast(s))
731
  {
732
    this->SetLayoutStrategyName("Fast 2D");
733
  }
734
  else if (vtkCircularLayoutStrategy::SafeDownCast(s))
735
  {
736
    this->SetLayoutStrategyName("Circular");
737
  }
738
  else if (vtkTreeLayoutStrategy::SafeDownCast(s))
739
  {
740
    this->SetLayoutStrategyName("Tree");
741
  }
742
  else if (vtkCosmicTreeLayoutStrategy::SafeDownCast(s))
743
  {
744
    this->SetLayoutStrategyName("Cosmic Tree");
745
  }
746
  else if (vtkPassThroughLayoutStrategy::SafeDownCast(s))
747
  {
748
    this->SetLayoutStrategyName("Pass Through");
749
  }
750
  else if (vtkConeLayoutStrategy::SafeDownCast(s))
751
  {
752
    this->SetLayoutStrategyName("Cone");
753
  }
754
  else if (vtkSpanTreeLayoutStrategy::SafeDownCast(s))
755
  {
756
    this->SetLayoutStrategyName("Span Tree");
757
  }
758
  else
759
  {
760
    this->SetLayoutStrategyName("Unknown");
761
  }
762 763 764 765 766 767 768 769 770 771
  this->Layout->SetLayoutStrategy(s);
}

vtkGraphLayoutStrategy* vtkRenderedGraphRepresentation::GetLayoutStrategy()
{
  return this->Layout->GetLayoutStrategy();
}

void vtkRenderedGraphRepresentation::SetLayoutStrategy(const char* name)
{
772
  std::string str = name;
773
  std::transform(str.begin(), str.end(), str.begin(), tolower);
774
  str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
775 776 777
  vtkSmartPointer<vtkGraphLayoutStrategy> strategy =
    vtkSmartPointer<vtkPassThroughLayoutStrategy>::New();
  if (str == "random")
778
  {
779
    strategy = vtkSmartPointer<vtkRandomLayoutStrategy>::New();
780
  }
781
  else if (str == "forcedirected")
782
  {
783
    strategy = vtkSmartPointer<vtkForceDirectedLayoutStrategy>::New();
784
  }
785
  else if (str == "simple2d")
786
  {
787
    strategy = vtkSmartPointer<vtkSimple2DLayoutStrategy>::New();
788
  }
789
  else if (str == "clustering2d")
790
  {
791
    strategy = vtkSmartPointer<vtkClustering2DLayoutStrategy>::New();
792
  }
793
  else if (str == "community2d")
794
  {
795
    strategy = vtkSmartPointer<vtkCommunity2DLayoutStrategy>::New();
796
  }
797
  else if (str == "fast2d")
798
  {
799
    strategy = vtkSmartPointer<vtkFast2DLayoutStrategy>::New();
800
  }
801
  else if (str == "circular")
802
  {
803
    strategy = vtkSmartPointer<vtkCircularLayoutStrategy>::New();
804
  }
805
  else if (str == "tree")
806
  {
807
    strategy = vtkSmartPointer<vtkTreeLayoutStrategy>::New();
808
  }
809
  else if (str == "cosmictree")
810
  {
811
    strategy = vtkSmartPointer<vtkCosmicTreeLayoutStrategy>::New();
812
  }
813
  else if (str == "cone")
814
  {
815
    strategy = vtkSmartPointer<vtkConeLayoutStrategy>::New();
816
  }
817
  else if (str == "spantree")
818
  {
819
    strategy = vtkSmartPointer<vtkSpanTreeLayoutStrategy>::New();
820
  }
821
  else if (str != "passthrough")
822
  {
823
    vtkErrorMacro("Unknown layout strategy: \"" << name << "\"");
824
  }
825 826
  std::string type1 = strategy->GetClassName();
  std::string type2 = this->GetLayoutStrategy()->GetClassName();
827
  if (type1 != type2)
828
  {
829
    this->SetLayoutStrategy(strategy);
830
  }
831 832 833 834 835 836 837 838 839 840
}

void vtkRenderedGraphRepresentation::SetLayoutStrategyToAssignCoordinates(
  const char* xarr,
  const char* yarr,
  const char* zarr)
{
  vtkAssignCoordinatesLayoutStrategy* s =
    vtkAssignCoordinatesLayoutStrategy::SafeDownCast(this->GetLayoutStrategy());
  if (!s)
841
  {
842 843 844
    s = vtkAssignCoordinatesLayoutStrategy::New();
    this->SetLayoutStrategy(s);
    s->Delete();
845
  }
846 847 848 849 850 851 852 853 854 855 856 857 858 859
  s->SetXCoordArrayName(xarr);
  s->SetYCoordArrayName(yarr);
  s->SetZCoordArrayName(zarr);
}

void vtkRenderedGraphRepresentation::SetLayoutStrategyToTree(
  bool radial,
  double angle,
  double leafSpacing,
  double logSpacing)
{
  vtkTreeLayoutStrategy* s =
    vtkTreeLayoutStrategy::SafeDownCast(this->GetLayoutStrategy());
  if (!s)
860
  {
861 862 863
    s = vtkTreeLayoutStrategy::New();
    this->SetLayoutStrategy(s);
    s->Delete();
864
  }
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
  s->SetRadial(radial);
  s->SetAngle(angle);
  s->SetLeafSpacing(leafSpacing);
  s->SetLogSpacingValue(logSpacing);
}

void vtkRenderedGraphRepresentation::SetLayoutStrategyToCosmicTree(
  const char* nodeSizeArrayName,
  bool sizeLeafNodesOnly,
  int layoutDepth,
  vtkIdType layoutRoot)
{
  vtkCosmicTreeLayoutStrategy* s =
    vtkCosmicTreeLayoutStrategy::SafeDownCast(this->GetLayoutStrategy());
  if (!s)
880
  {
881 882 883
    s = vtkCosmicTreeLayoutStrategy::New();
    this->SetLayoutStrategy(s);
    s->Delete();
884
  }
885 886 887 888 889 890 891 892 893
  s->SetNodeSizeArrayName(nodeSizeArrayName);
  s->SetSizeLeafNodesOnly(sizeLeafNodesOnly);
  s->SetLayoutDepth(layoutDepth);
  s->SetLayoutRoot(layoutRoot);
}

void vtkRenderedGraphRepresentation::SetEdgeLayoutStrategy(vtkEdgeLayoutStrategy* s)
{
  if (!s)
894
  {
895
    vtkErrorMacro("Layout strategy must not be nullptr.");
896
    return;
897
  }
898
  if (vtkArcParallelEdgeStrategy::SafeDownCast(s))
899
  {
900
    this->SetEdgeLayoutStrategyName("Arc Parallel");
901
  }
902
  else if (vtkGeoEdgeStrategy::SafeDownCast(s))
903
  {
904
    this->SetEdgeLayoutStrategyName("Geo");
905
  }
906
  else if (vtkPassThroughEdgeStrategy::SafeDownCast(s))
907
  {
908
    this->SetEdgeLayoutStrategyName("Pass Through");
909
  }
910
  else
911
  {
912
    this->SetEdgeLayoutStrategyName("Unknown");
913
  }
914 915 916 917 918 919 920 921 922 923
  this->EdgeLayout->SetLayoutStrategy(s);
}

vtkEdgeLayoutStrategy* vtkRenderedGraphRepresentation::GetEdgeLayoutStrategy()
{
  return this->EdgeLayout->GetLayoutStrategy();
}

void vtkRenderedGraphRepresentation::SetEdgeLayoutStrategy(const char* name)
{
924 925 926
  std::string str = name;
  std::transform(str.begin(), str.end(), str.begin(), tolower);
  str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
927 928 929
  vtkSmartPointer<vtkEdgeLayoutStrategy> strategy =
    vtkSmartPointer<vtkPassThroughEdgeStrategy>::New();
  if (str == "arcparallel")
930
  {
931
    strategy = vtkSmartPointer<vtkArcParallelEdgeStrategy>::New();
932
  }
933
  else if (str == "geo")
934
  {
935
    strategy = vtkSmartPointer<vtkGeoEdgeStrategy>::New();
936
  }
937
  else if (str != "passthrough")
938
  {
939
    vtkErrorMacro("Unknown layout strategy: \"" << name << "\"");
940
  }
941 942
  std::string type1 = strategy->GetClassName();
  std::string type2 = this->GetEdgeLayoutStrategy()->GetClassName();
943
  if (type1 != type2)
944
  {
945
    this->SetEdgeLayoutStrategy(strategy);
946
  }
947 948 949 950 951 952 953
}

void vtkRenderedGraphRepresentation::SetEdgeLayoutStrategyToGeo(double explodeFactor)
{
  vtkGeoEdgeStrategy* s =
    vtkGeoEdgeStrategy::SafeDownCast(this->GetLayoutStrategy());
  if (!s)
954
  {
955 956 957
    s = vtkGeoEdgeStrategy::New();
    this->SetEdgeLayoutStrategy(s);
    s->Delete();
958
  }
959 960 961 962 963 964 965 966
  s->SetExplodeFactor(explodeFactor);
}

bool vtkRenderedGraphRepresentation::AddToView(vtkView* view)
{
  this->Superclass::AddToView(view);
  vtkRenderView* rv = vtkRenderView::SafeDownCast(view);
  if (rv)
967
  {
968 969
    this->VertexScalarBar->SetInteractor(rv->GetRenderWindow()->GetInteractor());
    this->EdgeScalarBar->SetInteractor(rv->GetRenderWindow()->GetInteractor());
970 971
    this->VertexGlyph->SetRenderer(rv->GetRenderer());
    this->OutlineGlyph->SetRenderer(rv->GetRenderer());
972
    this->VertexIconTransform->SetViewport(rv->GetRenderer());
973 974 975 976 977
    rv->GetRenderer()->AddActor(this->OutlineActor);
    rv->GetRenderer()->AddActor(this->VertexActor);
    rv->GetRenderer()->AddActor(this->EdgeActor);
    rv->GetRenderer()->AddActor(this->VertexScalarBar->GetScalarBarActor());
    rv->GetRenderer()->AddActor(this->EdgeScalarBar->GetScalarBarActor());
978
    rv->GetRenderer()->AddActor(this->VertexIconActor);
979 980 981 982
    rv->AddLabels(this->VertexLabelHierarchy->GetOutputPort());
    rv->AddLabels(this->EdgeLabelHierarchy->GetOutputPort());
    //rv->AddIcons(this->VertexIconPriority->GetOutputPort());
    //rv->AddIcons(this->EdgeIconPriority->GetOutputPort());
983 984 985
    rv->RegisterProgress(this->Layout);
    rv->RegisterProgress(this->EdgeCenters);
    rv->RegisterProgress(this->GraphToPoints);
986 987
    rv->RegisterProgress(this->VertexLabelHierarchy);
    rv->RegisterProgress(this->EdgeLabelHierarchy);
988 989 990 991 992 993 994 995 996
    rv->RegisterProgress(this->Layout);
    rv->RegisterProgress(this->EdgeLayout);
    rv->RegisterProgress(this->GraphToPoly);
    rv->RegisterProgress(this->EdgeMapper);
    rv->RegisterProgress(this->VertexGlyph);
    rv->RegisterProgress(this->VertexMapper);
    rv->RegisterProgress(this->OutlineGlyph);
    rv->RegisterProgress(this->OutlineMapper);
    return true;
997
  }
998 999 1000 1001 1002 1003 1004 1005
  return false;
}

bool vtkRenderedGraphRepresentation::RemoveFromView(vtkView* view)
{
  this->Superclass::RemoveFromView(view);
  vtkRenderView* rv = vtkRenderView::SafeDownCast(view);
  if (rv)
1006
  {
1007 1008
    this->VertexGlyph->SetRenderer(nullptr);
    this->OutlineGlyph->SetRenderer(nullptr);
1009 1010 1011 1012 1013
    rv->GetRenderer()->RemoveActor(this->VertexActor);
    rv->GetRenderer()->RemoveActor(this->OutlineActor);
    rv->GetRenderer()->RemoveActor(this->EdgeActor);
    rv->GetRenderer()->RemoveActor(this->VertexScalarBar->GetScalarBarActor());
    rv->GetRenderer()->RemoveActor(this->EdgeScalarBar->GetScalarBarActor());
1014
    rv->GetRenderer()->RemoveActor(this->VertexIconActor);
1015 1016 1017 1018
    rv->RemoveLabels(this->VertexLabelHierarchy->GetOutputPort());
    rv->RemoveLabels(this->EdgeLabelHierarchy->GetOutputPort());
    //rv->RemoveIcons(this->VertexIcons->GetOutputPort());
    //rv->RemoveIcons(this->EdgeIcons->GetOutputPort());
1019 1020 1021
    rv->UnRegisterProgress(this->Layout);
    rv->UnRegisterProgress(this->EdgeCenters);
    rv->UnRegisterProgress(this->GraphToPoints);
1022 1023
    rv->UnRegisterProgress(this->VertexLabelHierarchy);
    rv->UnRegisterProgress(this->EdgeLabelHierarchy);
1024 1025 1026 1027 1028 1029 1030 1031 1032
    rv->UnRegisterProgress(this->Layout);
    rv->UnRegisterProgress(this->EdgeLayout);
    rv->UnRegisterProgress(this->GraphToPoly);
    rv->UnRegisterProgress(this->EdgeMapper);
    rv->UnRegisterProgress(this->VertexGlyph);
    rv->UnRegisterProgress(this->VertexMapper);
    rv->UnRegisterProgress(this->OutlineGlyph);
    rv->UnRegisterProgress(this->OutlineMapper);
    return true;
1033
  }
1034 1035 1036 1037 1038 1039 1040
  return false;
}

void vtkRenderedGraphRepresentation::PrepareForRendering(vtkRenderView* view)
{
  this->Superclass::PrepareForRendering(view);

1041 1042 1043
  this->VertexIconActor->SetTexture(view->GetIconTexture());
  if (this->VertexIconActor->GetTexture() &&
      this->VertexIconActor->GetTexture()->GetInput())
1044
  {
1045
    this->VertexIconGlyph->SetIconSize(view->GetIconSize());
1046 1047
    this->VertexIconGlyph->SetDisplaySize(view->GetDisplaySize());
    this->VertexIconGlyph->SetUseIconSize(false);
1048
    this->VertexIconActor->GetTexture()->SetColorMode(VTK_COLOR_MODE_DEFAULT);
1049
    this->VertexIconActor->GetTexture()->GetInputAlgorithm()->Update();
1050 1051
    int* dim = this->VertexIconActor->GetTexture()->GetInput()->GetDimensions();
    this->VertexIconGlyph->SetIconSheetSize(dim);
1052
  }
1053

1054 1055 1056 1057 1058
  // Make sure the transform is synchronized between rep and view
  this->Layout->SetTransform(view->GetTransform());
}

vtkSelection* vtkRenderedGraphRepresentation::ConvertSelection(
1059
  vtkView* vtkNotUsed(view), vtkSelection* sel)
1060
{
1061 1062
  // Search for selection nodes relating to the vertex and edges
  // of the graph.
1063 1064 1065 1066 1067 1068 1069
  vtkSmartPointer<vtkSelectionNode> vertexNode =
    vtkSmartPointer<vtkSelectionNode>::New();
  vtkSmartPointer<vtkSelectionNode> edgeNode =
    vtkSmartPointer<vtkSelectionNode>::New();
  bool foundEdgeNode = false;

  if (sel->GetNumberOfNodes() > 0)
1070
  {
1071
    for (unsigned int i = 0; i < sel->GetNumberOfNodes(); ++i)
1072
    {
1073 1074 1075 1076
      vtkSelectionNode* node = sel->GetNode(i);
      vtkProp* prop = vtkProp::SafeDownCast(
        node->GetProperties()->Get(vtkSelectionNode::PROP()));
      if (node->GetContentType() == vtkSelectionNode::FRUSTUM)
1077
      {
1078
        // A frustum selection can be used to select vertices and edges.
1079 1080
        vertexNode->ShallowCopy(node);
        edgeNode->ShallowCopy(node);
1081
        foundEdgeNode = true;
1082
      }
1083
      else if (prop == this->VertexActor.GetPointer())
1084
      {
1085 1086
        // The prop on the selection matches the vertex actor, so
        // this must have been a visible cell selection.
1087
        vertexNode->ShallowCopy(node);
1088
      }
1089
      else if (prop == this->EdgeActor.GetPointer())
1090
      {
1091 1092
        // The prop on the selection matches the edge actor, so
        // this must have been a visible cell selection.
1093 1094 1095 1096
        edgeNode->ShallowCopy(node);
        foundEdgeNode = true;
      }
    }
1097
  }
1098 1099

  // Remove the prop to avoid reference loops.
1100 1101 1102 1103
  vertexNode->GetProperties()->Remove(vtkSelectionNode::PROP());
  edgeNode->GetProperties()->Remove(vtkSelectionNode::PROP());

  vtkSelection* converted = vtkSelection::New();
1104
  vtkGraph* input = vtkGraph::SafeDownCast(this->GetInput());
1105
  if (!input)
1106
  {
1107
    return converted;
1108
  }
1109 1110 1111

  bool selectedVerticesFound = false;
  if (vertexNode)
1112
  {
1113 1114 1115 1116 1117 1118 1119 1120 1121
    // Convert a cell selection on the glyphed vertices into a
    // vertex selection on the graph of the appropriate type.

    // First, convert the cell selection on the polydata to
    // a pedigree ID selection (or index selection if there are no
    // pedigree IDs).
    vtkSmartPointer<vtkSelection> vertexSel =
      vtkSmartPointer<vtkSelection>::New();
    vertexSel->AddNode(vertexNode);
1122

1123 1124 1125 1126 1127
    vtkPolyData* poly = vtkPolyData::SafeDownCast(
      this->VertexGlyph->GetOutput());
    vtkSmartPointer<vtkTable> temp =
      vtkSmartPointer<vtkTable>::New();
    temp->SetRowData(vtkPolyData::SafeDownCast(poly)->GetCellData());
1128
    vtkSelection* polyConverted = nullptr;
1129
    if (poly->GetCellData()->GetPedigreeIds())
1130
    {
1131 1132
      polyConverted = vtkConvertSelection::ToSelectionType(
        vertexSel, poly, vtkSelectionNode::PEDIGREEIDS);
1133
    }
1134
    else
1135
    {
1136 1137
      polyConverted = vtkConvertSelection::ToSelectionType(
        vertexSel, poly, vtkSelectionNode::INDICES);
1138
    }
1139 1140 1141 1142 1143

    // Now that we have a pedigree or index selection, interpret this
    // as a vertex selection on the graph, and convert it to the
    // appropriate selection type for this representation.
    for (unsigned int i = 0; i < polyConverted->GetNumberOfNodes(); ++i)
1144
    {
1145
      polyConverted->GetNode(i)->SetFieldType(vtkSelectionNode::VERTEX);
1146
    }
1147 1148 1149 1150 1151
    vtkSelection* vertexConverted = vtkConvertSelection::ToSelectionType(
      polyConverted, input, this->SelectionType, this->SelectionArrayNames);

    // For all output selection nodes, select all the edges among selected vertices.
    for (unsigned int i = 0; i < vertexConverted->GetNumberOfNodes(); ++i)
1152
    {
1153 1154
      if ((vertexConverted->GetNode(i)->GetSelectionList()->
          GetNumberOfTuples() > 0) && (input->GetNumberOfEdges()) > 0)
1155
      {
1156 1157 1158 1159 1160 1161 1162
        // Get the list of selected vertices.
        selectedVerticesFound = true;
        vtkSmartPointer<vtkIdTypeArray> selectedVerts =
          vtkSmartPointer<vtkIdTypeArray>::New();
        vtkConvertSelection::GetSelectedVertices(
          vertexConverted, input, selectedVerts);

1163
        if( this->EdgeSelection )
1164
        {
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185
          // Get the list of induced edges on these vertices.
          vtkSmartPointer<vtkIdTypeArray> selectedEdges =
            vtkSmartPointer<vtkIdTypeArray>::New();
          input->GetInducedEdges(selectedVerts, selectedEdges);

          // Create an edge index selection containing the induced edges.
          vtkSmartPointer<vtkSelection> edgeSelection =
            vtkSmartPointer<vtkSelection>::New();
          vtkSmartPointer<vtkSelectionNode> edgeSelectionNode =
            vtkSmartPointer<vtkSelectionNode>::New();
          edgeSelectionNode->SetSelectionList(selectedEdges);
          edgeSelectionNode->SetContentType(vtkSelectionNode::INDICES);
          edgeSelectionNode->SetFieldType(vtkSelectionNode::EDGE);
          edgeSelection->AddNode(edgeSelectionNode);

          // Convert the edge selection to the appropriate type for this representation.
          vtkSelection* edgeConverted = vtkConvertSelection::ToSelectionType(
            edgeSelection, input, this->SelectionType, this->SelectionArrayNames);

          // Add the converted induced edge selection to the output selection.
          if (edgeConverted->GetNumberOfNodes() > 0)
1186
          {
1187
            converted->AddNode(edgeConverted->GetNode(0));
1188
          }
1189
          edgeConverted->Delete();
1190
        }
1191
      }
1192 1193 1194

      // Add the vertex selection node to the output selection.
      converted->AddNode(vertexConverted->GetNode(i));
1195
    }
1196 1197
    polyConverted->Delete();
    vertexConverted->Delete();
1198
  }
1199
  if (foundEdgeNode && !selectedVerticesFound && this->EdgeSelection)
1200
  {
1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
    // If no vertices were found (hence no induced edges), look for
    // edges that were within the selection box.

    // First, convert the cell selection on the polydata to
    // a pedigree ID selection (or index selection if there are no
    // pedigree IDs).
    vtkSmartPointer<vtkSelection> edgeSel =
      vtkSmartPointer<vtkSelection>::New();
    edgeSel->AddNode(edgeNode);
    vtkPolyData* poly = vtkPolyData::SafeDownCast(
      this->GraphToPoly->GetOutput());
1212
    vtkSelection* polyConverted = nullptr;
1213
    if (poly->GetCellData()->GetPedigreeIds())
1214
    {
1215 1216
      polyConverted = vtkConvertSelection::ToSelectionType(
        edgeSel, poly, vtkSelectionNode::PEDIGREEIDS);
1217
    }
1218
    else
1219
    {
1220 1221
      polyConverted = vtkConvertSelection::ToSelectionType(
        edgeSel, poly, vtkSelectionNode::INDICES);
1222
    }
1223 1224 1225 1226 1227

    // Now that we have a pedigree or index selection, interpret this
    // as an edge selection on the graph, and convert it to the
    // appropriate selection type for this representation.
    for (unsigned int i = 0; i < polyConverted->GetNumberOfNodes(); ++i)
1228
    {
1229
      polyConverted->GetNode(i)->SetFieldType(vtkSelectionNode::EDGE);
1230
    }
1231 1232 1233 1234 1235 1236 1237

    // Convert the edge selection to the appropriate type for this representation.
    vtkSelection* edgeConverted = vtkConvertSelection::ToSelectionType(
      polyConverted, input, this->SelectionType, this->SelectionArrayNames);

    // Add the vertex selection node to the output selection.
    for (unsigned int i = 0; i < edgeConverted->GetNumberOfNodes(); ++i)
1238
    {
1239
      converted->AddNode(edgeConverted->GetNode(i));
1240
    }
1241 1242
    polyConverted->Delete();
    edgeConverted->Delete();
1243
  }
1244 1245 1246
  return converted;
}

1247 1248 1249 1250
int vtkRenderedGraphRepresentation::RequestData(
  vtkInformation*,
  vtkInformationVector**,
  vtkInformationVector*)
1251
{
1252 1253
  this->Layout->SetInputConnection(this->GetInternalOutputPort());
  this->ApplyColors->SetInputConnection(1, this->GetInternalAnnotationOutputPort());
1254
  this->ApplyVertexIcons->SetInputConnection(1, this->GetInternalAnnotationOutputPort());
1255
  this->RemoveHiddenGraph->SetInputConnection(1, this->GetInternalAnnotationOutputPort());
1256
  return 1;
1257 1258 1259 1260 1261 1262
}

void vtkRenderedGraphRepresentation::ApplyViewTheme(vtkViewTheme* theme)
{
  this->Superclass::ApplyViewTheme(theme);

1263 1264
  this->ApplyColors->SetPointLookupTable(theme->GetPointLookupTable());
  this->ApplyColors->SetCellLookupTable(theme->GetCellLookupTable());
1265 1266
  this->VertexScalarBar->GetScalarBarActor()->SetLookupTable(theme->GetPointLookupTable());
  this->EdgeScalarBar->GetScalarBarActor()->SetLookupTable(theme->GetCellLookupTable());
1267 1268 1269 1270 1271 1272 1273 1274 1275

  this->ApplyColors->SetDefaultPointColor(theme->GetPointColor());
  this->ApplyColors->SetDefaultPointOpacity(theme->GetPointOpacity());
  this->ApplyColors->SetDefaultCellColor(theme->GetCellColor());
  this->ApplyColors->SetDefaultCellOpacity(theme->GetCellOpacity());
  this->ApplyColors->SetSelectedPointColor(theme->GetSelectedPointColor());
  this->ApplyColors->SetSelectedPointOpacity(theme->GetSelectedPointOpacity());
  this->ApplyColors->SetSelectedCellColor(theme->GetSelectedCellColor());
  this->ApplyColors->SetSelectedCellOpacity(theme->GetSelectedCellOpacity());
1276 1277
  this->ApplyColors->SetScalePointLookupTable(theme->GetScalePointLookupTable());
  this->ApplyColors->SetScaleCellLookupTable(theme->GetScaleCellLookupTable());
1278

1279 1280
  float baseSize = static_cast<float>(theme->GetPointSize());
  float lineWidth = static_cast<float>(theme->GetLineWidth());
1281 1282 1283
  this->VertexGlyph->SetScreenSize(baseSize);
  this->VertexActor->GetProperty()->SetPointSize(baseSize);
  this->OutlineGlyph->SetScreenSize(baseSize + 2);
1284 1285
  this->OutlineActor->GetProperty()->SetPointSize(baseSize + 2);
  this->OutlineActor->GetProperty()->SetLineWidth(1);
1286 1287 1288 1289
  this->EdgeActor->GetProperty()->SetLineWidth(lineWidth);

  this->OutlineActor->GetProperty()->SetColor(theme->GetOutlineColor());

1290 1291 1292 1293
  // FIXME: This is a strange hack to get around some weirdness with
  // the gradient background and multiple transparent actors (assuming
  // related to depth peeling or some junk...)
  if (theme->GetPointOpacity() == 0)
1294
  {
1295
    this->OutlineActor->VisibilityOff();
1296
  }
1297

1298
  this->GetVertexLabelTextProperty()->ShallowCopy(theme->GetPointTextProperty());
1299
  this->GetVertexLabelTextProperty()->SetLineOffset(-2*baseSize);
1300
  this->GetEdgeLabelTextProperty()->ShallowCopy(theme->GetCellTextProperty());
1301 1302 1303

  // Moronic hack.. the circles seem to be really small so make them bigger
  if (this->VertexGlyph->GetGlyphType() == vtkGraphToGlyphs::CIRCLE)
1304
  {
1305 1306
      this->VertexGlyph->SetScreenSize(baseSize*2+1);
      this->OutlineGlyph->SetScreenSize(baseSize*2+1);
1307
  }
1308