1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkHierarchicalGraphPipeline.cxx
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 "vtkHierarchicalGraphPipeline.h"
22 
23 #include "vtkActor.h"
24 #include "vtkActor2D.h"
25 #include "vtkApplyColors.h"
26 #include "vtkConvertSelection.h"
27 #include "vtkDataRepresentation.h"
28 #include "vtkDynamic2DLabelMapper.h"
29 #include "vtkEdgeCenters.h"
30 #include "vtkGraphHierarchicalBundleEdges.h"
31 #include "vtkGraphToPolyData.h"
32 #include "vtkInformation.h"
33 #include "vtkLookupTable.h"
34 #include "vtkObjectFactory.h"
35 #include "vtkPolyDataMapper.h"
36 #include "vtkProperty.h"
37 #include "vtkRenderView.h"
38 #include "vtkSelection.h"
39 #include "vtkSelectionNode.h"
40 #include "vtkSmartPointer.h"
41 #include "vtkSplineFilter.h"
42 #include "vtkSplineGraphEdges.h"
43 #include "vtkTextProperty.h"
44 #include "vtkViewTheme.h"
45 
46 vtkStandardNewMacro(vtkHierarchicalGraphPipeline);
47 
vtkHierarchicalGraphPipeline()48 vtkHierarchicalGraphPipeline::vtkHierarchicalGraphPipeline()
49 {
50   this->ApplyColors = vtkApplyColors::New();
51   this->Bundle = vtkGraphHierarchicalBundleEdges::New();
52   this->GraphToPoly = vtkGraphToPolyData::New();
53   this->Spline = vtkSplineGraphEdges::New();
54   this->Mapper = vtkPolyDataMapper::New();
55   this->Actor = vtkActor::New();
56   this->TextProperty = vtkTextProperty::New();
57   this->EdgeCenters = vtkEdgeCenters::New();
58   this->LabelMapper = vtkDynamic2DLabelMapper::New();
59   this->LabelActor = vtkActor2D::New();
60 
61   this->ColorArrayNameInternal = nullptr;
62   this->LabelArrayNameInternal = nullptr;
63   this->HoverArrayName = nullptr;
64 
65   /*
66   <graphviz>
67   digraph {
68     "Graph input" -> Bundle
69     "Tree input" -> Bundle
70     Bundle -> Spline -> ApplyColors -> GraphToPoly -> Mapper -> Actor
71     Spline -> EdgeCenters -> LabelMapper -> LabelActor
72   }
73   </graphviz>
74   */
75 
76   this->Spline->SetInputConnection(this->Bundle->GetOutputPort());
77   this->ApplyColors->SetInputConnection(this->Spline->GetOutputPort());
78   this->GraphToPoly->SetInputConnection(this->ApplyColors->GetOutputPort());
79   this->Mapper->SetInputConnection(this->GraphToPoly->GetOutputPort());
80   this->Actor->SetMapper(this->Mapper);
81 
82   this->EdgeCenters->SetInputConnection(this->Spline->GetOutputPort());
83   this->LabelMapper->SetInputConnection(this->EdgeCenters->GetOutputPort());
84   this->LabelMapper->SetLabelTextProperty(this->TextProperty);
85   this->LabelMapper->SetLabelModeToLabelFieldData();
86   this->LabelActor->SetMapper(this->LabelMapper);
87   this->LabelActor->VisibilityOff();
88 
89   this->Mapper->SetScalarModeToUseCellFieldData();
90   this->Mapper->SelectColorArray("vtkApplyColors color");
91   this->Mapper->ScalarVisibilityOn();
92   this->Actor->PickableOn();
93 
94   // Make sure this gets rendered on top
95   this->Actor->SetPosition(0.0, 0.0, 1.0);
96 
97   this->Bundle->SetBundlingStrength(0.5);
98   this->Spline->SetSplineType(vtkSplineGraphEdges::BSPLINE);
99   // this->Spline->SetNumberOfSubdivisions(4);
100 }
101 
~vtkHierarchicalGraphPipeline()102 vtkHierarchicalGraphPipeline::~vtkHierarchicalGraphPipeline()
103 {
104   this->SetColorArrayNameInternal(nullptr);
105   this->SetLabelArrayNameInternal(nullptr);
106   this->SetHoverArrayName(nullptr);
107   this->ApplyColors->Delete();
108   this->Bundle->Delete();
109   this->GraphToPoly->Delete();
110   this->Spline->Delete();
111   this->Mapper->Delete();
112   this->Actor->Delete();
113   this->TextProperty->Delete();
114   this->EdgeCenters->Delete();
115   this->LabelMapper->Delete();
116   this->LabelActor->Delete();
117 }
118 
RegisterProgress(vtkRenderView * rv)119 void vtkHierarchicalGraphPipeline::RegisterProgress(vtkRenderView* rv)
120 {
121   rv->RegisterProgress(this->ApplyColors);
122   rv->RegisterProgress(this->Bundle);
123   rv->RegisterProgress(this->ApplyColors);
124   rv->RegisterProgress(this->GraphToPoly);
125   rv->RegisterProgress(this->Spline);
126   rv->RegisterProgress(this->Mapper);
127 }
128 
SetBundlingStrength(double strength)129 void vtkHierarchicalGraphPipeline::SetBundlingStrength(double strength)
130 {
131   this->Bundle->SetBundlingStrength(strength);
132 }
133 
GetBundlingStrength()134 double vtkHierarchicalGraphPipeline::GetBundlingStrength()
135 {
136   return this->Bundle->GetBundlingStrength();
137 }
138 
SetLabelArrayName(const char * name)139 void vtkHierarchicalGraphPipeline::SetLabelArrayName(const char* name)
140 {
141   this->LabelMapper->SetFieldDataName(name);
142   this->SetLabelArrayNameInternal(name);
143 }
144 
GetLabelArrayName()145 const char* vtkHierarchicalGraphPipeline::GetLabelArrayName()
146 {
147   return this->GetLabelArrayNameInternal();
148 }
149 
SetLabelVisibility(bool vis)150 void vtkHierarchicalGraphPipeline::SetLabelVisibility(bool vis)
151 {
152   this->LabelActor->SetVisibility(vis);
153 }
154 
GetLabelVisibility()155 bool vtkHierarchicalGraphPipeline::GetLabelVisibility()
156 {
157   return (this->LabelActor->GetVisibility() ? true : false);
158 }
159 
SetLabelTextProperty(vtkTextProperty * prop)160 void vtkHierarchicalGraphPipeline::SetLabelTextProperty(vtkTextProperty* prop)
161 {
162   this->TextProperty->ShallowCopy(prop);
163 }
164 
GetLabelTextProperty()165 vtkTextProperty* vtkHierarchicalGraphPipeline::GetLabelTextProperty()
166 {
167   return this->TextProperty;
168 }
169 
SetColorArrayName(const char * name)170 void vtkHierarchicalGraphPipeline::SetColorArrayName(const char* name)
171 {
172   this->SetColorArrayNameInternal(name);
173   this->ApplyColors->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_EDGES, name);
174 }
175 
GetColorArrayName()176 const char* vtkHierarchicalGraphPipeline::GetColorArrayName()
177 {
178   return this->GetColorArrayNameInternal();
179 }
180 
SetColorEdgesByArray(bool vis)181 void vtkHierarchicalGraphPipeline::SetColorEdgesByArray(bool vis)
182 {
183   this->ApplyColors->SetUseCellLookupTable(vis);
184 }
185 
GetColorEdgesByArray()186 bool vtkHierarchicalGraphPipeline::GetColorEdgesByArray()
187 {
188   return this->ApplyColors->GetUseCellLookupTable();
189 }
190 
SetVisibility(bool vis)191 void vtkHierarchicalGraphPipeline::SetVisibility(bool vis)
192 {
193   this->Actor->SetVisibility(vis);
194 }
195 
GetVisibility()196 bool vtkHierarchicalGraphPipeline::GetVisibility()
197 {
198   return this->Actor->GetVisibility() ? true : false;
199 }
200 
SetSplineType(int type)201 void vtkHierarchicalGraphPipeline::SetSplineType(int type)
202 {
203   this->Spline->SetSplineType(type);
204 }
205 
GetSplineType()206 int vtkHierarchicalGraphPipeline::GetSplineType()
207 {
208   return this->Spline->GetSplineType();
209 }
210 
PrepareInputConnections(vtkAlgorithmOutput * graphConn,vtkAlgorithmOutput * treeConn,vtkAlgorithmOutput * annConn)211 void vtkHierarchicalGraphPipeline::PrepareInputConnections(
212   vtkAlgorithmOutput* graphConn, vtkAlgorithmOutput* treeConn, vtkAlgorithmOutput* annConn)
213 {
214   this->Bundle->SetInputConnection(0, graphConn);
215   this->Bundle->SetInputConnection(1, treeConn);
216   this->ApplyColors->SetInputConnection(1, annConn);
217 }
218 
ConvertSelection(vtkDataRepresentation * rep,vtkSelection * sel)219 vtkSelection* vtkHierarchicalGraphPipeline::ConvertSelection(
220   vtkDataRepresentation* rep, vtkSelection* sel)
221 {
222   vtkSelection* converted = vtkSelection::New();
223   for (unsigned int j = 0; j < sel->GetNumberOfNodes(); ++j)
224   {
225     vtkSelectionNode* node = sel->GetNode(j);
226     vtkProp* prop = vtkProp::SafeDownCast(node->GetProperties()->Get(vtkSelectionNode::PROP()));
227     if (prop == this->Actor)
228     {
229       vtkDataObject* input = this->Bundle->GetInputDataObject(0, 0);
230       vtkDataObject* poly = this->GraphToPoly->GetOutput();
231       vtkSmartPointer<vtkSelection> edgeSel = vtkSmartPointer<vtkSelection>::New();
232       vtkSmartPointer<vtkSelectionNode> nodeCopy = vtkSmartPointer<vtkSelectionNode>::New();
233       nodeCopy->ShallowCopy(node);
234       nodeCopy->GetProperties()->Remove(vtkSelectionNode::PROP());
235       edgeSel->AddNode(nodeCopy);
236       vtkSelection* polyConverted =
237         vtkConvertSelection::ToSelectionType(edgeSel, poly, vtkSelectionNode::PEDIGREEIDS);
238       for (unsigned int i = 0; i < polyConverted->GetNumberOfNodes(); ++i)
239       {
240         polyConverted->GetNode(i)->SetFieldType(vtkSelectionNode::EDGE);
241       }
242       vtkSelection* edgeConverted = vtkConvertSelection::ToSelectionType(
243         polyConverted, input, rep->GetSelectionType(), rep->GetSelectionArrayNames());
244       for (unsigned int i = 0; i < edgeConverted->GetNumberOfNodes(); ++i)
245       {
246         converted->AddNode(edgeConverted->GetNode(i));
247       }
248       polyConverted->Delete();
249       edgeConverted->Delete();
250     }
251   }
252   return converted;
253 }
254 
ApplyViewTheme(vtkViewTheme * theme)255 void vtkHierarchicalGraphPipeline::ApplyViewTheme(vtkViewTheme* theme)
256 {
257   this->ApplyColors->SetDefaultCellColor(theme->GetCellColor());
258   this->ApplyColors->SetDefaultCellOpacity(theme->GetCellOpacity());
259   this->ApplyColors->SetSelectedCellColor(theme->GetSelectedCellColor());
260   this->ApplyColors->SetSelectedCellOpacity(theme->GetSelectedCellOpacity());
261 
262   this->ApplyColors->SetCellLookupTable(theme->GetCellLookupTable());
263 
264   this->TextProperty->ShallowCopy(theme->GetCellTextProperty());
265   this->Actor->GetProperty()->SetLineWidth(theme->GetLineWidth());
266 }
267 
PrintSelf(ostream & os,vtkIndent indent)268 void vtkHierarchicalGraphPipeline::PrintSelf(ostream& os, vtkIndent indent)
269 {
270   this->Superclass::PrintSelf(os, indent);
271   os << indent << "Actor: ";
272   if (this->Actor && this->Bundle->GetNumberOfInputConnections(0) > 0)
273   {
274     os << "\n";
275     this->Actor->PrintSelf(os, indent.GetNextIndent());
276   }
277   else
278   {
279     os << "(none)\n";
280   }
281   os << indent << "LabelActor: ";
282   if (this->LabelActor && this->Bundle->GetNumberOfInputConnections(0) > 0)
283   {
284     os << "\n";
285     this->LabelActor->PrintSelf(os, indent.GetNextIndent());
286   }
287   else
288   {
289     os << "(none)\n";
290   }
291   os << indent << "HoverArrayName: " << (this->HoverArrayName ? this->HoverArrayName : "(none)")
292      << "\n";
293 }
294