1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataObjectTreeIterator.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 #include "vtkDataObjectTreeIterator.h"
16
17 #include "vtkDataObjectTree.h"
18 #include "vtkDataObjectTreeInternals.h"
19 #include "vtkObjectFactory.h"
20
21
22 class vtkDataObjectTreeIterator::vtkInternals
23 {
24 public:
25 // This implements a simple, no frills, depth-first iterator that iterates
26 // over the composite dataset.
27 class vtkIterator
28 {
29 vtkDataObject* DataObject;
30 vtkDataObjectTree* CompositeDataSet;
31
32 vtkDataObjectTreeInternals::Iterator Iter;
33 vtkDataObjectTreeInternals::ReverseIterator ReverseIter;
34 vtkIterator* ChildIterator;
35
36 vtkInternals* Parent;
37 bool Reverse;
38 bool PassSelf;
39 unsigned int ChildIndex;
40
InitChildIterator()41 void InitChildIterator()
42 {
43 if (!this->ChildIterator)
44 {
45 this->ChildIterator = new vtkIterator(this->Parent);
46 }
47 this->ChildIterator->Initialize(this->Reverse, 0);
48
49 if (this->Reverse &&
50 this->ReverseIter != this->GetInternals(this->CompositeDataSet)->Children.rend())
51 {
52 this->ChildIterator->Initialize(this->Reverse,
53 this->ReverseIter->DataObject);
54 }
55 else if (!this->Reverse &&
56 this->Iter != this->GetInternals(this->CompositeDataSet)->Children.end())
57 {
58 this->ChildIterator->Initialize(this->Reverse,
59 this->Iter->DataObject);
60 }
61 }
62
GetInternals(vtkDataObjectTree * cd)63 vtkDataObjectTreeInternals* GetInternals(vtkDataObjectTree* cd)
64 {
65 return this->Parent->GetInternals(cd);
66 }
67 public:
vtkIterator(vtkInternals * parent)68 vtkIterator(vtkInternals* parent)
69 {
70 this->ChildIterator = 0;
71 this->Parent = parent;
72 }
73
~vtkIterator()74 ~vtkIterator()
75 {
76 delete this->ChildIterator;
77 this->ChildIterator = 0;
78 }
79
80
81
Initialize(bool reverse,vtkDataObject * dataObj)82 void Initialize(bool reverse, vtkDataObject* dataObj)
83 {
84 vtkDataObjectTree* compositeData = vtkDataObjectTree::SafeDownCast(dataObj);
85 this->Reverse = reverse;
86 this->DataObject = dataObj;
87 this->CompositeDataSet = compositeData;
88 this->ChildIndex = 0;
89 this->PassSelf = true;
90
91 delete this->ChildIterator;
92 this->ChildIterator = NULL;
93
94 if (compositeData)
95 {
96 this->Iter = this->GetInternals(compositeData)->Children.begin();
97 this->ReverseIter = this->GetInternals(compositeData)->Children.rbegin();
98 this->InitChildIterator();
99 }
100 }
101
InSubTree()102 bool InSubTree()
103 {
104 if (this->PassSelf || this->IsDoneWithTraversal())
105 {
106 return false;
107 }
108
109 if (!this->ChildIterator)
110 {
111 return false;
112 }
113
114 if (this->ChildIterator->PassSelf)
115 {
116 return false;
117 }
118
119 return true;
120 }
121
122
IsDoneWithTraversal()123 bool IsDoneWithTraversal()
124 {
125 if (!this->DataObject)
126 {
127 return true;
128 }
129
130 if (this->PassSelf)
131 {
132 return false;
133 }
134
135 if (!this->CompositeDataSet)
136 {
137 return true;
138 }
139
140 if (this->Reverse &&
141 this->ReverseIter == this->GetInternals(this->CompositeDataSet)->Children.rend())
142 {
143 return true;
144 }
145
146 if (!this->Reverse &&
147 this->Iter == this->GetInternals(this->CompositeDataSet)->Children.end())
148 {
149 return true;
150 }
151 return false;
152 }
153
154 // Should not be called is this->IsDoneWithTraversal() returns true.
GetCurrentDataObject()155 vtkDataObject* GetCurrentDataObject()
156 {
157 if (this->PassSelf)
158 {
159 return this->DataObject;
160 }
161 return this->ChildIterator?
162 this->ChildIterator->GetCurrentDataObject() : 0;
163 }
164
GetCurrentMetaData()165 vtkInformation* GetCurrentMetaData()
166 {
167 if (this->PassSelf || !this->ChildIterator)
168 {
169 return NULL;
170 }
171
172 if (this->ChildIterator->PassSelf)
173 {
174 if (this->Reverse)
175 {
176 if (!this->ReverseIter->MetaData.GetPointer())
177 {
178 this->ReverseIter->MetaData.TakeReference(vtkInformation::New());
179 }
180 return this->ReverseIter->MetaData;
181 }
182 else
183 {
184 if (!this->Iter->MetaData.GetPointer())
185 {
186 this->Iter->MetaData.TakeReference(vtkInformation::New());
187 }
188 return this->Iter->MetaData;
189 }
190 }
191 return this->ChildIterator->GetCurrentMetaData();
192 }
193
HasCurrentMetaData()194 int HasCurrentMetaData()
195 {
196 if (this->PassSelf || !this->ChildIterator)
197 {
198 return 0;
199 }
200
201 if (this->ChildIterator->PassSelf)
202 {
203 return this->Reverse?
204 (this->ReverseIter->MetaData.GetPointer() != 0):
205 (this->Iter->MetaData.GetPointer() != 0);
206 }
207
208 return this->ChildIterator->HasCurrentMetaData();
209 }
210
211 // Go to the next element.
Next()212 void Next()
213 {
214 if (this->PassSelf)
215 {
216 this->PassSelf = false;
217 }
218 else if (this->ChildIterator)
219 {
220 this->ChildIterator->Next();
221 if (this->ChildIterator->IsDoneWithTraversal())
222 {
223 this->ChildIndex++;
224 if (this->Reverse)
225 {
226 this->ReverseIter++;
227 }
228 else
229 {
230 this->Iter++;
231 }
232 this->InitChildIterator();
233 }
234 }
235 }
236
237 // Returns the full-tree index for the current location.
GetCurrentIndex()238 vtkDataObjectTreeIndex GetCurrentIndex()
239 {
240 vtkDataObjectTreeIndex index;
241 if (this->PassSelf || this->IsDoneWithTraversal() || !this->ChildIterator)
242 {
243 return index;
244 }
245 index.push_back(this->ChildIndex);
246 vtkDataObjectTreeIndex childIndex = this->ChildIterator->GetCurrentIndex();
247 index.insert(index.end(), childIndex.begin(), childIndex.end());
248 return index;
249 }
250
251 };
252
253 // Description:
254 // Helper method used by vtkInternals to get access to the internals of
255 // vtkDataObjectTree.
GetInternals(vtkDataObjectTree * cd)256 vtkDataObjectTreeInternals* GetInternals(vtkDataObjectTree* cd)
257 {
258 return this->CompositeDataIterator->GetInternals(cd);
259 }
260
vtkInternals()261 vtkInternals()
262 {
263 this->Iterator = new vtkIterator(this);
264 }
~vtkInternals()265 ~vtkInternals()
266 {
267 delete this->Iterator;
268 this->Iterator = 0;
269 }
270
271 vtkIterator *Iterator;
272 vtkDataObjectTreeIterator* CompositeDataIterator;
273 };
274
275 vtkStandardNewMacro(vtkDataObjectTreeIterator);
276 //----------------------------------------------------------------------------
vtkDataObjectTreeIterator()277 vtkDataObjectTreeIterator::vtkDataObjectTreeIterator()
278 {
279 this->VisitOnlyLeaves = 1;
280 this->TraverseSubTree = 1;
281 this->CurrentFlatIndex = 0;
282 this->Internals = new vtkInternals();
283 this->Internals->CompositeDataIterator = this;
284 }
285
286 //----------------------------------------------------------------------------
~vtkDataObjectTreeIterator()287 vtkDataObjectTreeIterator::~vtkDataObjectTreeIterator()
288 {
289 delete this->Internals;
290 }
291
292 //----------------------------------------------------------------------------
IsDoneWithTraversal()293 int vtkDataObjectTreeIterator::IsDoneWithTraversal()
294 {
295 return this->Internals->Iterator->IsDoneWithTraversal();
296 }
297
298 //----------------------------------------------------------------------------
GoToFirstItem()299 void vtkDataObjectTreeIterator::GoToFirstItem()
300 {
301 this->CurrentFlatIndex = 0;
302 this->Internals->Iterator->Initialize(this->Reverse !=0, this->DataSet);
303 this->NextInternal();
304
305 while (!this->Internals->Iterator->IsDoneWithTraversal())
306 {
307 vtkDataObject* dObj = this->Internals->Iterator->GetCurrentDataObject();
308 if ((!dObj && this->SkipEmptyNodes) ||
309 (this->VisitOnlyLeaves && vtkDataObjectTree::SafeDownCast(dObj)))
310 {
311 this->NextInternal();
312 }
313 else
314 {
315 break;
316 }
317 }
318 }
319
320 //----------------------------------------------------------------------------
GoToNextItem()321 void vtkDataObjectTreeIterator::GoToNextItem()
322 {
323 if (!this->Internals->Iterator->IsDoneWithTraversal())
324 {
325 this->NextInternal();
326
327 while (!this->Internals->Iterator->IsDoneWithTraversal())
328 {
329 vtkDataObject* dObj = this->Internals->Iterator->GetCurrentDataObject();
330 if ((!dObj && this->SkipEmptyNodes) ||
331 (this->VisitOnlyLeaves && vtkDataObjectTree::SafeDownCast(dObj)))
332 {
333 this->NextInternal();
334 }
335 else
336 {
337 break;
338 }
339 }
340 }
341 }
342
343 //----------------------------------------------------------------------------
NextInternal()344 void vtkDataObjectTreeIterator::NextInternal()
345 {
346 do
347 {
348 this->CurrentFlatIndex++;
349 this->Internals->Iterator->Next();
350 }
351 while (!this->TraverseSubTree && this->Internals->Iterator->InSubTree());
352 }
353
354 //----------------------------------------------------------------------------
GetCurrentDataObject()355 vtkDataObject* vtkDataObjectTreeIterator::GetCurrentDataObject()
356 {
357 if (!this->IsDoneWithTraversal())
358 {
359 return this->Internals->Iterator->GetCurrentDataObject();
360 }
361
362 return 0;
363 }
364
365 //----------------------------------------------------------------------------
GetCurrentMetaData()366 vtkInformation* vtkDataObjectTreeIterator::GetCurrentMetaData()
367 {
368 if (!this->IsDoneWithTraversal())
369 {
370 return this->Internals->Iterator->GetCurrentMetaData();
371 }
372
373 return 0;
374 }
375
376 //----------------------------------------------------------------------------
HasCurrentMetaData()377 int vtkDataObjectTreeIterator::HasCurrentMetaData()
378 {
379 if (!this->IsDoneWithTraversal())
380 {
381 return this->Internals->Iterator->HasCurrentMetaData();
382 }
383
384 return 0;
385 }
386
387 //----------------------------------------------------------------------------
GetCurrentIndex()388 vtkDataObjectTreeIndex vtkDataObjectTreeIterator::GetCurrentIndex()
389 {
390 return this->Internals->Iterator->GetCurrentIndex();
391 }
392
393 //----------------------------------------------------------------------------
GetCurrentFlatIndex()394 unsigned int vtkDataObjectTreeIterator::GetCurrentFlatIndex()
395 {
396 if (this->Reverse)
397 {
398 vtkErrorMacro(
399 "FlatIndex cannot be obtained when iterating in reverse order.");
400 return 0;
401 }
402 return this->CurrentFlatIndex;
403 }
404
405 //----------------------------------------------------------------------------
GetInternals(vtkDataObjectTree * cd)406 vtkDataObjectTreeInternals* vtkDataObjectTreeIterator::GetInternals(
407 vtkDataObjectTree* cd)
408 {
409 if (cd)
410 {
411 return cd->Internals;
412 }
413
414 return 0;
415 }
416
417 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)418 void vtkDataObjectTreeIterator::PrintSelf(ostream& os, vtkIndent indent)
419 {
420 this->Superclass::PrintSelf(os, indent);
421 os << indent << "VisitOnlyLeaves: "
422 << (this->VisitOnlyLeaves? "On" : "Off") << endl;
423 os << indent << "Reverse: "
424 << (this->Reverse? "On" : "Off") << endl;
425 os << indent << "TraverseSubTree: "
426 << (this->TraverseSubTree? "On" : "Off") << endl;
427 os << indent << "SkipEmptyNodes: "
428 << (this->SkipEmptyNodes? "On" : "Off") << endl;
429 os << indent << "CurrentFlatIndex: " << this->CurrentFlatIndex << endl;
430 }
431