1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkTreeMapLayout.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 "vtkTreeMapLayout.h"
22
23 #include "vtkAdjacentVertexIterator.h"
24 #include "vtkCellArray.h"
25 #include "vtkCellData.h"
26 #include "vtkDataArray.h"
27 #include "vtkFloatArray.h"
28 #include "vtkInformation.h"
29 #include "vtkInformationVector.h"
30 #include "vtkMath.h"
31 #include "vtkObjectFactory.h"
32 #include "vtkPointData.h"
33 #include "vtkTree.h"
34 #include "vtkTreeMapLayoutStrategy.h"
35
36 vtkStandardNewMacro(vtkTreeMapLayout);
37
vtkTreeMapLayout()38 vtkTreeMapLayout::vtkTreeMapLayout()
39 {
40 this->RectanglesFieldName = nullptr;
41 this->LayoutStrategy = nullptr;
42 this->SetRectanglesFieldName("area");
43 this->SetSizeArrayName("size");
44 }
45
~vtkTreeMapLayout()46 vtkTreeMapLayout::~vtkTreeMapLayout()
47 {
48 this->SetRectanglesFieldName(nullptr);
49 if (this->LayoutStrategy)
50 {
51 this->LayoutStrategy->Delete();
52 }
53 }
54
55 vtkCxxSetObjectMacro(vtkTreeMapLayout, LayoutStrategy, vtkTreeMapLayoutStrategy);
56
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)57 int vtkTreeMapLayout::RequestData(vtkInformation* vtkNotUsed(request),
58 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
59 {
60 if (this->LayoutStrategy == nullptr)
61 {
62 vtkErrorMacro(<< "Layout strategy must be non-null.");
63 return 0;
64 }
65 if (this->RectanglesFieldName == nullptr)
66 {
67 vtkErrorMacro(<< "Rectangles field name must be non-null.");
68 return 0;
69 }
70 // get the info objects
71 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
72 vtkInformation* outInfo = outputVector->GetInformationObject(0);
73
74 // Storing the inputTree and outputTree handles
75 vtkTree* inputTree = vtkTree::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
76 vtkTree* outputTree = vtkTree::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
77
78 // Copy the input into the output
79 outputTree->ShallowCopy(inputTree);
80
81 // Add the 4-tuple array that will store the min,max xy coords
82 vtkFloatArray* coordsArray = vtkFloatArray::New();
83 coordsArray->SetName(this->RectanglesFieldName);
84 coordsArray->SetNumberOfComponents(4);
85 coordsArray->SetNumberOfTuples(inputTree->GetNumberOfVertices());
86 vtkDataSetAttributes* data = outputTree->GetVertexData();
87 data->AddArray(coordsArray);
88 coordsArray->Delete();
89
90 // Add the 4-tuple array that will store the min,max xy coords
91 vtkDataArray* sizeArray = this->GetInputArrayToProcess(0, inputTree);
92 if (!sizeArray)
93 {
94 vtkErrorMacro("Size array not found.");
95 return 0;
96 }
97
98 // Okay now layout the tree :)
99 this->LayoutStrategy->Layout(inputTree, coordsArray, sizeArray);
100
101 return 1;
102 }
103
PrintSelf(ostream & os,vtkIndent indent)104 void vtkTreeMapLayout::PrintSelf(ostream& os, vtkIndent indent)
105 {
106 this->Superclass::PrintSelf(os, indent);
107 os << indent << "RectanglesFieldName: "
108 << (this->RectanglesFieldName ? this->RectanglesFieldName : "(none)") << endl;
109 os << indent << "LayoutStrategy: " << (this->LayoutStrategy ? "" : "(none)") << endl;
110 if (this->LayoutStrategy)
111 {
112 this->LayoutStrategy->PrintSelf(os, indent.GetNextIndent());
113 }
114 }
115
FindVertex(float pnt[2],float * binfo)116 vtkIdType vtkTreeMapLayout::FindVertex(float pnt[2], float* binfo)
117 {
118 // Do we have an output?
119 vtkTree* otree = this->GetOutput();
120 if (!otree)
121 {
122 vtkErrorMacro(<< "Could not get output tree.");
123 return -1;
124 }
125
126 // Get the four tuple array for the points
127 vtkDataArray* array = otree->GetVertexData()->GetArray(this->RectanglesFieldName);
128 if (!array)
129 {
130 // vtkErrorMacro(<< "Output Tree does not have box information.");
131 return -1;
132 }
133
134 // Check to see that we are in the dataset at all
135 float blimits[4];
136
137 vtkIdType vertex = otree->GetRoot();
138 vtkFloatArray* boxInfo = vtkArrayDownCast<vtkFloatArray>(array);
139 // Now try to find the vertex that contains the point
140 boxInfo->GetTypedTuple(vertex, blimits); // Get the extents of the root
141 if ((pnt[0] < blimits[0]) || (pnt[0] > blimits[1]) || (pnt[1] < blimits[2]) ||
142 (pnt[1] > blimits[3]))
143 {
144 // Point is not in the tree at all
145 return -1;
146 }
147
148 // Now traverse the children to try and find
149 // the vertex that contains the point
150 vtkIdType child;
151 if (binfo)
152 {
153 binfo[0] = blimits[0];
154 binfo[1] = blimits[1];
155 binfo[2] = blimits[2];
156 binfo[3] = blimits[3];
157 }
158
159 vtkAdjacentVertexIterator* it = vtkAdjacentVertexIterator::New();
160 otree->GetAdjacentVertices(vertex, it);
161 while (it->HasNext())
162 {
163 child = it->Next();
164 boxInfo->GetTypedTuple(child, blimits); // Get the extents of the child
165 if ((pnt[0] < blimits[0]) || (pnt[0] > blimits[1]) || (pnt[1] < blimits[2]) ||
166 (pnt[1] > blimits[3]))
167 {
168 continue;
169 }
170 // If we are here then the point is contained by the child
171 // So recurse down the children of this vertex
172 vertex = child;
173 otree->GetAdjacentVertices(vertex, it);
174 }
175 it->Delete();
176
177 return vertex;
178 }
179
GetBoundingBox(vtkIdType id,float * binfo)180 void vtkTreeMapLayout::GetBoundingBox(vtkIdType id, float* binfo)
181 {
182 // Do we have an output?
183 vtkTree* otree = this->GetOutput();
184 if (!otree)
185 {
186 vtkErrorMacro(<< "Could not get output tree.");
187 return;
188 }
189
190 // Get the four tuple array for the points
191 vtkDataArray* array = otree->GetVertexData()->GetArray(this->RectanglesFieldName);
192 if (!array)
193 {
194 // vtkErrorMacro(<< "Output Tree does not have box information.");
195 return;
196 }
197
198 vtkFloatArray* boxInfo = vtkArrayDownCast<vtkFloatArray>(array);
199 boxInfo->GetTypedTuple(id, binfo);
200 }
201
GetMTime()202 vtkMTimeType vtkTreeMapLayout::GetMTime()
203 {
204 vtkMTimeType mTime = this->Superclass::GetMTime();
205 vtkMTimeType time;
206
207 if (this->LayoutStrategy != nullptr)
208 {
209 time = this->LayoutStrategy->GetMTime();
210 mTime = (time > mTime ? time : mTime);
211 }
212 return mTime;
213 }
214