1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataObjectTree.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 "vtkDataObjectTree.h"
16
17 #include "vtkDataObjectTreeIterator.h"
18 #include "vtkDataObjectTreeInternals.h"
19 #include "vtkDataSet.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationStringKey.h"
22 #include "vtkInformationIntegerKey.h"
23 #include "vtkInformationVector.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkMultiPieceDataSet.h"
26
27
28 //----------------------------------------------------------------------------
vtkDataObjectTree()29 vtkDataObjectTree::vtkDataObjectTree()
30 {
31 this->Internals = new vtkDataObjectTreeInternals;
32 }
33
34 //----------------------------------------------------------------------------
~vtkDataObjectTree()35 vtkDataObjectTree::~vtkDataObjectTree()
36 {
37 delete this->Internals;
38 }
39
40 //----------------------------------------------------------------------------
GetData(vtkInformation * info)41 vtkDataObjectTree* vtkDataObjectTree::GetData(vtkInformation* info)
42 {
43 return info? vtkDataObjectTree::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
44 }
45
46 //----------------------------------------------------------------------------
GetData(vtkInformationVector * v,int i)47 vtkDataObjectTree* vtkDataObjectTree::GetData(vtkInformationVector* v,
48 int i)
49 {
50 return vtkDataObjectTree::GetData(v->GetInformationObject(i));
51 }
52
53 //----------------------------------------------------------------------------
SetNumberOfChildren(unsigned int num)54 void vtkDataObjectTree::SetNumberOfChildren(unsigned int num)
55 {
56 this->Internals->Children.resize(num);
57 this->Modified();
58 }
59
60 //----------------------------------------------------------------------------
GetNumberOfChildren()61 unsigned int vtkDataObjectTree::GetNumberOfChildren()
62 {
63 return static_cast<unsigned int>(this->Internals->Children.size());
64 }
65
66 //----------------------------------------------------------------------------
SetChild(unsigned int index,vtkDataObject * dobj)67 void vtkDataObjectTree::SetChild(unsigned int index, vtkDataObject* dobj)
68 {
69 if (this->Internals->Children.size() <= index)
70 {
71 this->SetNumberOfChildren(index+1);
72 }
73
74 vtkDataObjectTreeItem& item = this->Internals->Children[index];
75 if(item.DataObject!=dobj)
76 {
77 item.DataObject = dobj;
78 this->Modified();
79 }
80 }
81
82 //----------------------------------------------------------------------------
RemoveChild(unsigned int index)83 void vtkDataObjectTree::RemoveChild(unsigned int index)
84 {
85 if (this->Internals->Children.size() <= index)
86 {
87 vtkErrorMacro("The input index is out of range.");
88 return;
89 }
90
91 vtkDataObjectTreeItem& item = this->Internals->Children[index];
92 item.DataObject = NULL;
93 this->Internals->Children.erase(this->Internals->Children.begin()+index);
94 this->Modified();
95 }
96
97 //----------------------------------------------------------------------------
GetChild(unsigned int index)98 vtkDataObject* vtkDataObjectTree::GetChild(unsigned int index)
99 {
100 if (index < this->Internals->Children.size())
101 {
102 return this->Internals->Children[index].DataObject;
103 }
104
105 return 0;
106 }
107
108 //----------------------------------------------------------------------------
GetChildMetaData(unsigned int index)109 vtkInformation* vtkDataObjectTree::GetChildMetaData(unsigned int index)
110 {
111 if (index < this->Internals->Children.size())
112 {
113 vtkDataObjectTreeItem& item = this->Internals->Children[index];
114 if (!item.MetaData)
115 {
116 // New vtkInformation is allocated is none is already present.
117 item.MetaData.TakeReference(vtkInformation::New());
118 }
119 return item.MetaData;
120 }
121 return 0;
122 }
123
124 //----------------------------------------------------------------------------
SetChildMetaData(unsigned int index,vtkInformation * info)125 void vtkDataObjectTree::SetChildMetaData(unsigned int index, vtkInformation* info)
126 {
127 if (this->Internals->Children.size() <= index)
128 {
129 this->SetNumberOfChildren(index+1);
130 }
131
132 vtkDataObjectTreeItem& item = this->Internals->Children[index];
133 item.MetaData = info;
134 }
135
136 //----------------------------------------------------------------------------
HasChildMetaData(unsigned int index)137 int vtkDataObjectTree::HasChildMetaData(unsigned int index)
138 {
139 if (index < this->Internals->Children.size())
140 {
141 vtkDataObjectTreeItem& item = this->Internals->Children[index];
142 return (item.MetaData.GetPointer() != NULL)? 1 : 0;
143 }
144
145 return 0;
146 }
147
148 //----------------------------------------------------------------------------
CopyStructure(vtkCompositeDataSet * compositeSource)149 void vtkDataObjectTree::CopyStructure(vtkCompositeDataSet* compositeSource)
150 {
151 if(!compositeSource)
152 {
153 return;
154 }
155 vtkDataObjectTree* source = vtkDataObjectTree::SafeDownCast(compositeSource);
156 if (source == this)
157 {
158 return;
159 }
160
161 this->Internals->Children.clear();
162 if (!source)
163 {
164 //WARNING:
165 //If we copy the structure of from a non-tree composite data set
166 //we create a special structure of two levels, the first level
167 //is just a single multipiece and the second level are all the data sets.
168 //This is likely to change in the future!
169 vtkMultiPieceDataSet* mds = vtkMultiPieceDataSet::New();
170 this->SetChild(0, mds);
171 mds->Delete();
172
173 vtkInformation* info = vtkInformation::New();
174 info->Set(vtkCompositeDataSet::NAME(),"All Blocks");
175 this->SetChildMetaData(0, info);
176 info->FastDelete();
177
178
179 int totalNumBlocks=0;
180 vtkCompositeDataIterator* iter = compositeSource->NewIterator();
181 iter->SkipEmptyNodesOff();
182 for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
183 {
184 totalNumBlocks++;
185 }
186 iter->Delete();
187
188 mds->SetNumberOfChildren(totalNumBlocks);
189 return;
190 }
191
192 this->Internals->Children.resize(source->Internals->Children.size());
193
194 vtkDataObjectTreeInternals::Iterator srcIter =
195 source->Internals->Children.begin();
196 vtkDataObjectTreeInternals::Iterator myIter =
197 this->Internals->Children.begin();
198 for (; srcIter != source->Internals->Children.end(); ++srcIter, myIter++)
199 {
200 vtkDataObjectTree* compositeSrc =
201 vtkDataObjectTree::SafeDownCast(srcIter->DataObject);
202 if (compositeSrc)
203 {
204 vtkDataObjectTree* copy = compositeSrc->NewInstance();
205 myIter->DataObject.TakeReference(copy);
206 copy->CopyStructure(compositeSrc);
207 }
208
209 // shallow copy meta data.
210 if (srcIter->MetaData)
211 {
212 vtkInformation* info = vtkInformation::New();
213 info->Copy(srcIter->MetaData, /*deep=*/0);
214 myIter->MetaData = info;
215 info->FastDelete();
216 }
217 }
218 this->Modified();
219 }
220
221 //----------------------------------------------------------------------------
NewTreeIterator()222 vtkDataObjectTreeIterator* vtkDataObjectTree::NewTreeIterator()
223 {
224 vtkDataObjectTreeIterator* iter = vtkDataObjectTreeIterator::New();
225 iter->SetDataSet(this);
226 return iter;
227 }
228
229 //----------------------------------------------------------------------------
NewIterator()230 vtkCompositeDataIterator* vtkDataObjectTree::NewIterator()
231 {
232 return this->NewTreeIterator();
233 }
234
235 //----------------------------------------------------------------------------
SetDataSet(vtkCompositeDataIterator * iter,vtkDataObject * dataObj)236 void vtkDataObjectTree::SetDataSet(vtkCompositeDataIterator* iter,
237 vtkDataObject* dataObj)
238 {
239 vtkDataObjectTreeIterator* treeIter = vtkDataObjectTreeIterator::SafeDownCast(iter);
240 if(treeIter)
241 {
242 this->SetDataSetFrom(treeIter,dataObj);
243 return;
244 }
245
246 if (!iter || iter->IsDoneWithTraversal())
247 {
248 vtkErrorMacro("Invalid iterator location.");
249 return;
250 }
251
252
253 //WARNING: We are doing something special here. See comments
254 // in CopyStructure()
255
256 unsigned int index = iter->GetCurrentFlatIndex();
257 if(this->GetNumberOfChildren()!=1)
258 {
259 vtkErrorMacro("Structure is not expected. Did you forget to use copy structure?");
260 return;
261 }
262 vtkMultiPieceDataSet* parent = vtkMultiPieceDataSet::SafeDownCast(this->GetChild(0));
263 if(!parent)
264 {
265 vtkErrorMacro("Structure is not expected. Did you forget to use copy structure?");
266 return;
267 }
268 parent->SetChild(index, dataObj);
269 }
270
271 //----------------------------------------------------------------------------
SetDataSetFrom(vtkDataObjectTreeIterator * iter,vtkDataObject * dataObj)272 void vtkDataObjectTree::SetDataSetFrom(vtkDataObjectTreeIterator* iter,
273 vtkDataObject* dataObj)
274 {
275 if (!iter || iter->IsDoneWithTraversal())
276 {
277 vtkErrorMacro("Invalid iterator location.");
278 return;
279 }
280
281 vtkDataObjectTreeIndex index = iter->GetCurrentIndex();
282
283 if (index.size() == 0)
284 {
285 // Sanity check.
286 vtkErrorMacro("Invalid index returned by iterator.");
287 return;
288 }
289
290 vtkDataObjectTree* parent = this;
291 int numIndices = static_cast<int>(index.size());
292 for (int cc=0; cc < numIndices-1; cc++)
293 {
294 if (!parent || parent->GetNumberOfChildren() <= index[cc])
295 {
296 vtkErrorMacro("Structure does not match. "
297 "You must use CopyStructure before calling this method.");
298 return;
299 }
300 parent = vtkDataObjectTree::SafeDownCast(parent->GetChild(index[cc]));
301 }
302
303 if (!parent || parent->GetNumberOfChildren() <= index.back())
304 {
305 vtkErrorMacro("Structure does not match. "
306 "You must use CopyStructure before calling this method.");
307 return;
308 }
309
310 parent->SetChild(index.back(), dataObj);
311 }
312
313 //----------------------------------------------------------------------------
GetDataSet(vtkCompositeDataIterator * compositeIter)314 vtkDataObject* vtkDataObjectTree::GetDataSet(vtkCompositeDataIterator* compositeIter)
315 {
316 if (!compositeIter || compositeIter->IsDoneWithTraversal())
317 {
318 vtkErrorMacro("Invalid iterator location.");
319 return 0;
320 }
321
322 vtkDataObjectTreeIterator* iter = vtkDataObjectTreeIterator::SafeDownCast(compositeIter);
323 if (!iter)
324 {
325 //WARNING: We are doing something special here. See comments
326 // in CopyStructure()
327 //To do: More clear check of structures here. At least something like this->Depth()==1
328 unsigned int currentFlatIndex = compositeIter->GetCurrentFlatIndex();
329
330 if(this->GetNumberOfChildren()!=1)
331 {
332 vtkErrorMacro("Structure is not expected. Did you forget to use copy structure?");
333 return NULL;
334 }
335 vtkMultiPieceDataSet* parent = vtkMultiPieceDataSet::SafeDownCast(this->GetChild(0));
336 if(!parent)
337 {
338 vtkErrorMacro("Structure is not expected. Did you forget to use copy structure?");
339 return NULL;
340 }
341
342 if(currentFlatIndex < parent->GetNumberOfChildren())
343 {
344 return parent->GetChild(currentFlatIndex);
345 }
346 else
347 {
348 return NULL;
349 }
350 }
351
352 vtkDataObjectTreeIndex index = iter->GetCurrentIndex();
353
354 if (index.size() == 0)
355 {
356 // Sanity check.
357 vtkErrorMacro("Invalid index returned by iterator.");
358 return 0;
359 }
360
361 vtkDataObjectTree* parent = this;
362 int numIndices = static_cast<int>(index.size());
363 for (int cc=0; cc < numIndices-1; cc++)
364 {
365 if (!parent || parent->GetNumberOfChildren() <= index[cc])
366 {
367 vtkErrorMacro("Structure does not match. "
368 "You must use CopyStructure before calling this method.");
369 return 0;
370 }
371 parent = vtkDataObjectTree::SafeDownCast(parent->GetChild(index[cc]));
372 }
373
374 if (!parent || parent->GetNumberOfChildren() <= index.back())
375 {
376 vtkErrorMacro("Structure does not match. "
377 "You must use CopyStructure before calling this method.");
378 return 0;
379 }
380
381 return parent->GetChild(index.back());
382 }
383
384 //----------------------------------------------------------------------------
GetMetaData(vtkCompositeDataIterator * compositeIter)385 vtkInformation* vtkDataObjectTree::GetMetaData(vtkCompositeDataIterator* compositeIter)
386 {
387 vtkDataObjectTreeIterator* iter = vtkDataObjectTreeIterator::SafeDownCast(compositeIter);
388 if (!iter || iter->IsDoneWithTraversal())
389 {
390 vtkErrorMacro("Invalid iterator location.");
391 return 0;
392 }
393
394 vtkDataObjectTreeIndex index = iter->GetCurrentIndex();
395
396 if (index.size() == 0)
397 {
398 // Sanity check.
399 vtkErrorMacro("Invalid index returned by iterator.");
400 return 0;
401 }
402
403 vtkDataObjectTree* parent = this;
404 int numIndices = static_cast<int>(index.size());
405 for (int cc=0; cc < numIndices-1; cc++)
406 {
407 if (!parent || parent->GetNumberOfChildren() <= index[cc])
408 {
409 vtkErrorMacro("Structure does not match. "
410 "You must use CopyStructure before calling this method.");
411 return 0;
412 }
413 parent = vtkDataObjectTree::SafeDownCast(parent->GetChild(index[cc]));
414 }
415
416 if (!parent || parent->GetNumberOfChildren() <= index.back())
417 {
418 vtkErrorMacro("Structure does not match. "
419 "You must use CopyStructure before calling this method.");
420 return 0;
421 }
422
423 return parent->GetChildMetaData(index.back());
424 }
425
426 //----------------------------------------------------------------------------
HasMetaData(vtkCompositeDataIterator * compositeIter)427 int vtkDataObjectTree::HasMetaData(vtkCompositeDataIterator* compositeIter)
428 {
429 vtkDataObjectTreeIterator* iter = vtkDataObjectTreeIterator::SafeDownCast(compositeIter);
430 if (!iter || iter->IsDoneWithTraversal())
431 {
432 vtkErrorMacro("Invalid iterator location.");
433 return 0;
434 }
435
436 vtkDataObjectTreeIndex index = iter->GetCurrentIndex();
437
438 if (index.size() == 0)
439 {
440 // Sanity check.
441 vtkErrorMacro("Invalid index returned by iterator.");
442 return 0;
443 }
444
445 vtkDataObjectTree* parent = this;
446 int numIndices = static_cast<int>(index.size());
447 for (int cc=0; cc < numIndices-1; cc++)
448 {
449 if (!parent || parent->GetNumberOfChildren() <= index[cc])
450 {
451 vtkErrorMacro("Structure does not match. "
452 "You must use CopyStructure before calling this method.");
453 return 0;
454 }
455 parent = vtkDataObjectTree::SafeDownCast(parent->GetChild(index[cc]));
456 }
457
458 if (!parent || parent->GetNumberOfChildren() <= index.back())
459 {
460 vtkErrorMacro("Structure does not match. "
461 "You must use CopyStructure before calling this method.");
462 return 0;
463 }
464
465 return parent->HasChildMetaData(index.back());
466 }
467
468 //----------------------------------------------------------------------------
ShallowCopy(vtkDataObject * src)469 void vtkDataObjectTree::ShallowCopy(vtkDataObject* src)
470 {
471 if (src == this)
472 {
473 return;
474 }
475
476 this->Internals->Children.clear();
477 this->Superclass::ShallowCopy(src);
478
479 vtkDataObjectTree* from = vtkDataObjectTree::SafeDownCast(src);
480 if (from)
481 {
482 unsigned int numChildren = from->GetNumberOfChildren();
483 this->SetNumberOfChildren(numChildren);
484 for (unsigned int cc=0; cc < numChildren; cc++)
485 {
486 vtkDataObject* child = from->GetChild(cc);
487 if (child)
488 {
489 if (child->IsA("vtkDataObjectTree"))
490 {
491 vtkDataObject* clone = child->NewInstance();
492 clone->ShallowCopy(child);
493 this->SetChild(cc, clone);
494 clone->FastDelete();
495 }
496 else
497 {
498 this->SetChild(cc, child);
499 }
500 }
501 if (from->HasChildMetaData(cc))
502 {
503 vtkInformation* toInfo = this->GetChildMetaData(cc);
504 toInfo->Copy(from->GetChildMetaData(cc), /*deep=*/0);
505 }
506 }
507 }
508 this->Modified();
509 }
510
511 //----------------------------------------------------------------------------
DeepCopy(vtkDataObject * src)512 void vtkDataObjectTree::DeepCopy(vtkDataObject* src)
513 {
514 if (src == this)
515 {
516 return;
517 }
518
519 this->Internals->Children.clear();
520 this->Superclass::DeepCopy(src);
521
522 vtkDataObjectTree* from = vtkDataObjectTree::SafeDownCast(src);
523 if (from)
524 {
525 unsigned int numChildren = from->GetNumberOfChildren();
526 this->SetNumberOfChildren(numChildren);
527 for (unsigned int cc=0; cc < numChildren; cc++)
528 {
529 vtkDataObject* fromChild = from->GetChild(cc);
530 if (fromChild)
531 {
532 vtkDataObject* toChild = fromChild->NewInstance();
533 toChild->DeepCopy(fromChild);
534 this->SetChild(cc, toChild);
535 toChild->FastDelete();
536 if (from->HasChildMetaData(cc))
537 {
538 vtkInformation* toInfo = this->GetChildMetaData(cc);
539 toInfo->Copy(from->GetChildMetaData(cc), /*deep=*/1);
540 }
541 }
542 }
543 }
544 this->Modified();
545 }
546
547 //----------------------------------------------------------------------------
Initialize()548 void vtkDataObjectTree::Initialize()
549 {
550 this->Internals->Children.clear();
551 this->Superclass::Initialize();
552 }
553
554 //----------------------------------------------------------------------------
GetNumberOfPoints()555 vtkIdType vtkDataObjectTree::GetNumberOfPoints()
556 {
557 vtkIdType numPts = 0;
558 vtkDataObjectTreeIterator* iter = vtkDataObjectTreeIterator::SafeDownCast(this->NewIterator());
559 for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
560 {
561 vtkDataSet* ds = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject());
562 if (ds)
563 {
564 numPts += ds->GetNumberOfPoints();
565 }
566 }
567 iter->Delete();
568 return numPts;
569 }
570
571
572 //----------------------------------------------------------------------------
GetActualMemorySize()573 unsigned long vtkDataObjectTree::GetActualMemorySize()
574 {
575 unsigned long memSize = 0;
576 vtkDataObjectTreeIterator* iter = vtkDataObjectTreeIterator::SafeDownCast(this->NewIterator());
577 for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
578 {
579 vtkDataObject* dobj = iter->GetCurrentDataObject();
580 memSize += dobj->GetActualMemorySize();
581 }
582 iter->Delete();
583 return memSize;
584 }
585
586 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)587 void vtkDataObjectTree::PrintSelf(ostream& os, vtkIndent indent)
588 {
589 this->Superclass::PrintSelf(os, indent);
590 os << indent << "Number Of Children: " << this->GetNumberOfChildren() << endl;
591 for (unsigned int cc=0; cc < this->GetNumberOfChildren(); cc++)
592 {
593 vtkDataObject* child = this->GetChild(cc);
594 if (child)
595 {
596 os << indent << "Child " << cc << ": " << child->GetClassName() << endl;
597 child->PrintSelf(os, indent.GetNextIndent());
598 }
599 else
600 {
601 os << indent << "Child " << cc << ": NULL" << endl;
602 }
603 }
604 }
605