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