1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkFieldData.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 "vtkFieldData.h"
16 
17 #include "vtkDataArray.h"
18 #include "vtkIdList.h"
19 #include "vtkInformation.h"
20 #include "vtkObjectFactory.h"
21 
22 vtkStandardNewMacro(vtkFieldData);
23 vtkStandardExtendedNewMacro(vtkFieldData);
24 
25 //------------------------------------------------------------------------------
NullData(vtkIdType id)26 void vtkFieldData::NullData(vtkIdType id)
27 {
28   vtkFieldData::Iterator it(this);
29   vtkDataArray* da;
30   std::vector<double> tuple(32, .0);
31   for (da = it.Begin(); !it.End(); da = it.Next())
32   {
33     if (da)
34     {
35       const size_t numComps = static_cast<size_t>(da->GetNumberOfComponents());
36       if (numComps > tuple.size())
37       {
38         tuple.resize(numComps, .0);
39       }
40       da->InsertTuple(id, tuple.data());
41     }
42   }
43 }
44 
45 //------------------------------------------------------------------------------
BasicIterator(const int * list,unsigned int listSize)46 vtkFieldData::BasicIterator::BasicIterator(const int* list, unsigned int listSize)
47 {
48   this->Position = 0;
49 
50   if (list)
51   {
52     if (listSize > 0)
53     {
54       this->List.assign(list, list + listSize);
55     }
56     else
57     {
58       this->List.clear();
59     }
60   }
61   else
62   {
63     this->List.clear();
64   }
65 }
66 
67 //------------------------------------------------------------------------------
Iterator(vtkFieldData * dsa,const int * list,unsigned int lSize)68 vtkFieldData::Iterator::Iterator(vtkFieldData* dsa, const int* list, unsigned int lSize)
69   : vtkFieldData::BasicIterator(list, lSize)
70 {
71   this->Fields = dsa;
72   dsa->Register(nullptr);
73   if (!list)
74   {
75     int listSize = dsa->GetNumberOfArrays();
76     this->List.reserve(listSize);
77     for (int i = 0; i < listSize; i++)
78     {
79       this->List.push_back(i);
80     }
81   }
82   this->Detached = 0;
83 }
84 
85 //------------------------------------------------------------------------------
BasicIterator(const vtkFieldData::BasicIterator & source)86 vtkFieldData::BasicIterator::BasicIterator(const vtkFieldData::BasicIterator& source)
87 {
88   this->List = source.List;
89 }
90 
91 //------------------------------------------------------------------------------
Iterator(const vtkFieldData::Iterator & source)92 vtkFieldData::Iterator::Iterator(const vtkFieldData::Iterator& source)
93   : vtkFieldData::BasicIterator(source)
94 {
95   this->Detached = source.Detached;
96   this->Fields = source.Fields;
97   if (this->Fields && !this->Detached)
98   {
99     this->Fields->Register(nullptr);
100   }
101 }
102 
103 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)104 void vtkFieldData::BasicIterator::PrintSelf(ostream& os, vtkIndent indent)
105 {
106   os << indent << "BasicIterator:{";
107   size_t listSize = this->List.size();
108   if (listSize > 0)
109   {
110     os << this->List[0];
111     for (size_t i = 1; i < listSize; ++i)
112     {
113       os << ", " << this->List[i];
114     }
115   }
116   os << "}" << endl;
117 }
118 
119 //------------------------------------------------------------------------------
operator =(const vtkFieldData::BasicIterator & source)120 vtkFieldData::BasicIterator& vtkFieldData::BasicIterator::operator=(
121   const vtkFieldData::BasicIterator& source)
122 {
123   if (this == &source)
124   {
125     return *this;
126   }
127 
128   this->List = source.List;
129 
130   return *this;
131 }
132 
133 //------------------------------------------------------------------------------
operator =(const vtkFieldData::Iterator & source)134 vtkFieldData::Iterator& vtkFieldData::Iterator::operator=(const vtkFieldData::Iterator& source)
135 {
136   if (this == &source)
137   {
138     return *this;
139   }
140   this->BasicIterator::operator=(source);
141   if (this->Fields && !this->Detached)
142   {
143     this->Fields->UnRegister(nullptr);
144   }
145   this->Fields = source.Fields;
146   this->Detached = source.Detached;
147   if (this->Fields && !this->Detached)
148   {
149     this->Fields->Register(nullptr);
150   }
151   return *this;
152 }
153 
154 //------------------------------------------------------------------------------
~Iterator()155 vtkFieldData::Iterator::~Iterator()
156 {
157   if (this->Fields && !this->Detached)
158   {
159     this->Fields->UnRegister(nullptr);
160   }
161 }
162 
163 //------------------------------------------------------------------------------
DetachFieldData()164 void vtkFieldData::Iterator::DetachFieldData()
165 {
166   if (this->Fields && !this->Detached)
167   {
168     this->Fields->UnRegister(nullptr);
169     this->Detached = 1;
170   }
171 }
172 
173 //------------------------------------------------------------------------------
174 // Construct object with no data initially.
vtkFieldData()175 vtkFieldData::vtkFieldData()
176 {
177   this->NumberOfArrays = 0;
178   this->Data = nullptr;
179   this->NumberOfActiveArrays = 0;
180 
181   this->CopyFieldFlags = nullptr;
182   this->NumberOfFieldFlags = 0;
183 
184   this->DoCopyAllOn = 1;
185   this->DoCopyAllOff = 0;
186 
187   this->CopyAllOn();
188 }
189 
190 //------------------------------------------------------------------------------
~vtkFieldData()191 vtkFieldData::~vtkFieldData()
192 {
193   this->Initialize();
194   this->ClearFieldFlags();
195 }
196 
197 //------------------------------------------------------------------------------
198 // Release all data but do not delete object.
InitializeFields()199 void vtkFieldData::InitializeFields()
200 {
201   int i;
202 
203   if (this->Data)
204   {
205     for (i = 0; i < this->GetNumberOfArrays(); i++)
206     {
207       this->Data[i]->UnRegister(this);
208     }
209 
210     delete[] this->Data;
211     this->Data = nullptr;
212   }
213 
214   this->NumberOfArrays = 0;
215   this->NumberOfActiveArrays = 0;
216   this->Modified();
217 }
218 
219 //------------------------------------------------------------------------------
220 // Release all data but do not delete object.
221 // Also initialize copy flags.
Initialize()222 void vtkFieldData::Initialize()
223 {
224   this->InitializeFields();
225   this->CopyAllOn();
226   this->ClearFieldFlags();
227 }
228 
229 //------------------------------------------------------------------------------
230 // Allocate data for each array.
Allocate(vtkIdType sz,vtkIdType ext)231 vtkTypeBool vtkFieldData::Allocate(vtkIdType sz, vtkIdType ext)
232 {
233   int i;
234   int status = 0;
235 
236   for (i = 0; i < this->GetNumberOfArrays(); i++)
237   {
238     if ((status = this->Data[i]->Allocate(sz, ext)) == 0)
239     {
240       break;
241     }
242   }
243 
244   return status;
245 }
246 
247 //------------------------------------------------------------------------------
CopyStructure(vtkFieldData * r)248 void vtkFieldData::CopyStructure(vtkFieldData* r)
249 {
250   // Free old fields.
251   this->InitializeFields();
252 
253   // Allocate new fields.
254   this->AllocateArrays(r->GetNumberOfArrays());
255   this->NumberOfActiveArrays = r->GetNumberOfArrays();
256 
257   // Copy the data array's structure (ie nTups,nComps,name, and info)
258   // don't copy their data.
259   int i;
260   vtkAbstractArray* data;
261   for (i = 0; i < r->GetNumberOfArrays(); ++i)
262   {
263     data = r->Data[i]->NewInstance();
264     int numComponents = r->Data[i]->GetNumberOfComponents();
265     data->SetNumberOfComponents(numComponents);
266     data->SetName(r->Data[i]->GetName());
267     for (vtkIdType j = 0; j < numComponents; j++)
268     {
269       data->SetComponentName(j, r->Data[i]->GetComponentName(j));
270     }
271     if (r->Data[i]->HasInformation())
272     {
273       data->CopyInformation(r->Data[i]->GetInformation(), /*deep=*/1);
274     }
275     this->SetArray(i, data);
276     data->Delete();
277   }
278 }
279 
280 //------------------------------------------------------------------------------
281 // Set the number of arrays used to define the field.
AllocateArrays(int num)282 void vtkFieldData::AllocateArrays(int num)
283 {
284   int i;
285 
286   if (num < 0)
287   {
288     num = 0;
289   }
290 
291   if (num == this->NumberOfArrays)
292   {
293     return;
294   }
295 
296   if (num == 0)
297   {
298     this->Initialize();
299   }
300   else if (num < this->NumberOfArrays)
301   {
302     for (i = num; i < this->NumberOfArrays; i++)
303     {
304       if (this->Data[i])
305       {
306         this->Data[i]->UnRegister(this);
307       }
308     }
309     this->NumberOfArrays = num;
310   }
311   else // num > this->NumberOfArrays
312   {
313     vtkAbstractArray** data = new vtkAbstractArray*[num];
314     // copy the original data
315     for (i = 0; i < this->NumberOfArrays; i++)
316     {
317       data[i] = this->Data[i];
318     }
319 
320     // initialize the new arrays
321     for (i = this->NumberOfArrays; i < num; i++)
322     {
323       data[i] = nullptr;
324     }
325 
326     // get rid of the old data
327     delete[] this->Data;
328 
329     // update object
330     this->Data = data;
331     this->NumberOfArrays = num;
332   }
333   this->Modified();
334 }
335 
336 //------------------------------------------------------------------------------
337 // Set an array to define the field.
SetArray(int i,vtkAbstractArray * data)338 void vtkFieldData::SetArray(int i, vtkAbstractArray* data)
339 {
340   if (!data || (i > this->NumberOfActiveArrays))
341   {
342     vtkWarningMacro("Can not set array " << i << " to " << data << endl);
343     return;
344   }
345 
346   if (i < 0)
347   {
348     vtkWarningMacro("Array index should be >= 0");
349     return;
350   }
351   else if (i >= this->NumberOfArrays)
352   {
353     this->AllocateArrays(i + 1);
354     this->NumberOfActiveArrays = i + 1;
355   }
356 
357   if (this->Data[i] != data)
358   {
359     if (this->Data[i] != nullptr)
360     {
361       this->Data[i]->UnRegister(this);
362     }
363     this->Data[i] = data;
364     if (this->Data[i] != nullptr)
365     {
366       this->Data[i]->Register(this);
367     }
368     this->Modified();
369   }
370 }
371 
372 //------------------------------------------------------------------------------
373 // Return the ith array in the field. A nullptr is returned if the index i is out
374 // if range.
GetArray(int i)375 vtkDataArray* vtkFieldData::GetArray(int i)
376 {
377   return vtkArrayDownCast<vtkDataArray>(this->GetAbstractArray(i));
378 }
379 
380 //------------------------------------------------------------------------------
381 // Return the ith array in the field. A nullptr is returned if the index i is out
382 // if range.
GetAbstractArray(int i)383 vtkAbstractArray* vtkFieldData::GetAbstractArray(int i)
384 {
385   if (i < 0 || i >= this->GetNumberOfArrays() || this->Data == nullptr)
386   {
387     return nullptr;
388   }
389   return this->Data[i];
390 }
391 
392 //------------------------------------------------------------------------------
393 // Copy a field by creating new data arrays
DeepCopy(vtkFieldData * f)394 void vtkFieldData::DeepCopy(vtkFieldData* f)
395 {
396   vtkAbstractArray *data, *newData;
397 
398   this->AllocateArrays(f->GetNumberOfArrays());
399   for (int i = 0; i < f->GetNumberOfArrays(); i++)
400   {
401     data = f->GetAbstractArray(i);
402     newData = data->NewInstance(); // instantiate same type of object
403     newData->DeepCopy(data);
404     newData->SetName(data->GetName());
405     if (data->HasInformation())
406     {
407       newData->CopyInformation(data->GetInformation(), /*deep=*/1);
408     }
409     this->AddArray(newData);
410     newData->Delete();
411   }
412 }
413 
414 //------------------------------------------------------------------------------
415 // Copy a field by reference counting the data arrays.
ShallowCopy(vtkFieldData * f)416 void vtkFieldData::ShallowCopy(vtkFieldData* f)
417 {
418   this->AllocateArrays(f->GetNumberOfArrays());
419   this->NumberOfActiveArrays = 0;
420 
421   for (int i = 0; i < f->GetNumberOfArrays(); i++)
422   {
423     this->NumberOfActiveArrays++;
424     this->SetArray(i, f->GetAbstractArray(i));
425   }
426   this->CopyFlags(f);
427 }
428 
429 //------------------------------------------------------------------------------
430 // Squeezes each data array in the field (Squeeze() reclaims unused memory.)
Squeeze()431 void vtkFieldData::Squeeze()
432 {
433   for (int i = 0; i < this->GetNumberOfArrays(); i++)
434   {
435     this->Data[i]->Squeeze();
436   }
437 }
438 
439 //------------------------------------------------------------------------------
440 // Resets each data array in the field (Reset() does not release memory but
441 // it makes the arrays look like they are empty.)
Reset()442 void vtkFieldData::Reset()
443 {
444   int i;
445 
446   for (i = 0; i < this->GetNumberOfArrays(); i++)
447   {
448     this->Data[i]->Reset();
449   }
450 }
451 
452 //------------------------------------------------------------------------------
453 // Get a field from a list of ids. Supplied field f should have same
454 // types and number of data arrays as this one (i.e., like
455 // CopyStructure() creates).
GetField(vtkIdList * ptIds,vtkFieldData * f)456 void vtkFieldData::GetField(vtkIdList* ptIds, vtkFieldData* f)
457 {
458   int i, numIds = ptIds->GetNumberOfIds();
459 
460   for (i = 0; i < numIds; i++)
461   {
462     f->InsertTuple(i, ptIds->GetId(i), this);
463   }
464 }
465 
466 //------------------------------------------------------------------------------
467 // Return the array containing the ith component of the field. The return value
468 // is an integer number n 0<=n<this->NumberOfArrays. Also, an integer value is
469 // returned indicating the component in the array is returned. Method returns
470 // -1 if specified component is not in field.
GetArrayContainingComponent(int i,int & arrayComp)471 int vtkFieldData::GetArrayContainingComponent(int i, int& arrayComp)
472 {
473   int numComp, count = 0;
474 
475   for (int j = 0; j < this->GetNumberOfArrays(); j++)
476   {
477     if (this->Data[j] != nullptr)
478     {
479       numComp = this->Data[j]->GetNumberOfComponents();
480       if (i < (numComp + count))
481       {
482         arrayComp = i - count;
483         return j;
484       }
485       count += numComp;
486     }
487   }
488   return -1;
489 }
490 
491 //------------------------------------------------------------------------------
GetArray(const char * arrayName,int & index)492 vtkDataArray* vtkFieldData::GetArray(const char* arrayName, int& index)
493 {
494   int i;
495   vtkDataArray* da = vtkArrayDownCast<vtkDataArray>(this->GetAbstractArray(arrayName, i));
496   index = (da) ? i : -1;
497   return da;
498 }
499 
500 //------------------------------------------------------------------------------
GetAbstractArray(const char * arrayName,int & index)501 vtkAbstractArray* vtkFieldData::GetAbstractArray(const char* arrayName, int& index)
502 {
503   int i;
504   const char* name;
505   index = -1;
506   if (!arrayName)
507   {
508     return nullptr;
509   }
510   for (i = 0; i < this->GetNumberOfArrays(); i++)
511   {
512     name = this->GetArrayName(i);
513     if (name && !strcmp(name, arrayName))
514     {
515       index = i;
516       return this->GetAbstractArray(i);
517     }
518   }
519   return nullptr;
520 }
521 
522 //------------------------------------------------------------------------------
AddArray(vtkAbstractArray * array)523 int vtkFieldData::AddArray(vtkAbstractArray* array)
524 {
525   if (!array)
526   {
527     return -1;
528   }
529 
530   int index;
531   this->GetAbstractArray(array->GetName(), index);
532 
533   if (index == -1)
534   {
535     index = this->NumberOfActiveArrays;
536     this->NumberOfActiveArrays++;
537   }
538   this->SetArray(index, array);
539   return index;
540 }
541 
542 //------------------------------------------------------------------------------
RemoveArray(const char * name)543 void vtkFieldData::RemoveArray(const char* name)
544 {
545   int i;
546   this->GetAbstractArray(name, i);
547   this->RemoveArray(i);
548 }
549 
550 //------------------------------------------------------------------------------
RemoveArray(int index)551 void vtkFieldData::RemoveArray(int index)
552 {
553   if ((index < 0) || (index >= this->NumberOfActiveArrays))
554   {
555     return;
556   }
557   this->Data[index]->UnRegister(this);
558   this->Data[index] = nullptr;
559   this->NumberOfActiveArrays--;
560   for (int i = index; i < this->NumberOfActiveArrays; i++)
561   {
562     this->Data[i] = this->Data[i + 1];
563   }
564   this->Data[this->NumberOfActiveArrays] = nullptr;
565   this->Modified();
566 }
567 
568 //------------------------------------------------------------------------------
GetActualMemorySize()569 unsigned long vtkFieldData::GetActualMemorySize()
570 {
571   unsigned long size = 0;
572 
573   for (int i = 0; i < this->GetNumberOfArrays(); i++)
574   {
575     if (this->Data[i] != nullptr)
576     {
577       size += this->Data[i]->GetActualMemorySize();
578     }
579   }
580 
581   return size;
582 }
583 
584 //------------------------------------------------------------------------------
GetMTime()585 vtkMTimeType vtkFieldData::GetMTime()
586 {
587   vtkMTimeType mTime = this->MTime;
588   vtkMTimeType otherMTime;
589   vtkAbstractArray* aa;
590 
591   for (int i = 0; i < this->NumberOfActiveArrays; i++)
592   {
593     if ((aa = this->Data[i]))
594     {
595       otherMTime = aa->GetMTime();
596       if (otherMTime > mTime)
597       {
598         mTime = otherMTime;
599       }
600     }
601   }
602 
603   return mTime;
604 }
605 
606 //------------------------------------------------------------------------------
CopyFieldOnOff(const char * field,int onOff)607 void vtkFieldData::CopyFieldOnOff(const char* field, int onOff)
608 {
609   if (!field)
610   {
611     return;
612   }
613 
614   int index;
615   // If the array is in the list, simply set IsCopied to onOff
616   if ((index = this->FindFlag(field)) != -1)
617   {
618     if (this->CopyFieldFlags[index].IsCopied != onOff)
619     {
620       this->CopyFieldFlags[index].IsCopied = onOff;
621       this->Modified();
622     }
623   }
624   else
625   {
626     // We need to reallocate the list of fields
627     vtkFieldData::CopyFieldFlag* newFlags =
628       new vtkFieldData::CopyFieldFlag[this->NumberOfFieldFlags + 1];
629     // Copy old flags (pointer copy for name)
630     for (int i = 0; i < this->NumberOfFieldFlags; i++)
631     {
632       newFlags[i].ArrayName = this->CopyFieldFlags[i].ArrayName;
633       newFlags[i].IsCopied = this->CopyFieldFlags[i].IsCopied;
634     }
635     // Copy new flag (strcpy)
636     char* newName = new char[strlen(field) + 1];
637     strcpy(newName, field);
638     newFlags[this->NumberOfFieldFlags].ArrayName = newName;
639     newFlags[this->NumberOfFieldFlags].IsCopied = onOff;
640     this->NumberOfFieldFlags++;
641     delete[] this->CopyFieldFlags;
642     this->CopyFieldFlags = newFlags;
643     this->Modified();
644   }
645 }
646 
647 //------------------------------------------------------------------------------
648 // Turn on copying of all data.
CopyAllOn(int vtkNotUsed (ctype))649 void vtkFieldData::CopyAllOn(int vtkNotUsed(ctype))
650 {
651   if (!DoCopyAllOn || DoCopyAllOff)
652   {
653     this->DoCopyAllOn = 1;
654     this->DoCopyAllOff = 0;
655     this->Modified();
656   }
657 }
658 
659 //------------------------------------------------------------------------------
660 // Turn off copying of all data.
CopyAllOff(int vtkNotUsed (ctype))661 void vtkFieldData::CopyAllOff(int vtkNotUsed(ctype))
662 {
663   if (DoCopyAllOn || !DoCopyAllOff)
664   {
665     this->DoCopyAllOn = 0;
666     this->DoCopyAllOff = 1;
667     this->Modified();
668   }
669 }
670 
671 //------------------------------------------------------------------------------
672 // Deallocate and clear the list of fields.
ClearFieldFlags()673 void vtkFieldData::ClearFieldFlags()
674 {
675   if (this->NumberOfFieldFlags > 0)
676   {
677     for (int i = 0; i < this->NumberOfFieldFlags; i++)
678     {
679       delete[] this->CopyFieldFlags[i].ArrayName;
680     }
681   }
682   delete[] this->CopyFieldFlags;
683   this->CopyFieldFlags = nullptr;
684   this->NumberOfFieldFlags = 0;
685 }
686 
687 //------------------------------------------------------------------------------
688 // Find if field is in CopyFieldFlags.
689 // If it is, it returns the index otherwise it returns -1
FindFlag(const char * field)690 int vtkFieldData::FindFlag(const char* field)
691 {
692   if (!field)
693     return -1;
694   for (int i = 0; i < this->NumberOfFieldFlags; i++)
695   {
696     if (this->CopyFieldFlags[i].ArrayName && !strcmp(field, this->CopyFieldFlags[i].ArrayName))
697     {
698       return i;
699     }
700   }
701   return -1;
702 }
703 
704 //------------------------------------------------------------------------------
705 // If there is no flag for this array, return -1.
706 // If there is one: return 0 if off, 1 if on
GetFlag(const char * field)707 int vtkFieldData::GetFlag(const char* field)
708 {
709   int index = this->FindFlag(field);
710   if (index == -1)
711   {
712     return -1;
713   }
714   else
715   {
716     return this->CopyFieldFlags[index].IsCopied;
717   }
718 }
719 
720 //------------------------------------------------------------------------------
721 // Copy the fields list (with strcpy)
CopyFlags(const vtkFieldData * source)722 void vtkFieldData::CopyFlags(const vtkFieldData* source)
723 {
724   this->ClearFieldFlags();
725   this->NumberOfFieldFlags = source->NumberOfFieldFlags;
726   if (this->NumberOfFieldFlags > 0)
727   {
728     this->CopyFieldFlags = new vtkFieldData::CopyFieldFlag[this->NumberOfFieldFlags];
729     for (int i = 0; i < this->NumberOfFieldFlags; i++)
730     {
731       this->CopyFieldFlags[i].ArrayName = new char[strlen(source->CopyFieldFlags[i].ArrayName) + 1];
732       strcpy(this->CopyFieldFlags[i].ArrayName, source->CopyFieldFlags[i].ArrayName);
733     }
734   }
735   else
736   {
737     this->CopyFieldFlags = nullptr;
738   }
739 }
740 
741 //------------------------------------------------------------------------------
PassData(vtkFieldData * fd)742 void vtkFieldData::PassData(vtkFieldData* fd)
743 {
744   for (int i = 0; i < fd->GetNumberOfArrays(); i++)
745   {
746     const char* arrayName = fd->GetArrayName(i);
747     // If there is no blocker for the given array
748     // and both CopyAllOff and CopyOn for that array are not true
749     if ((this->GetFlag(arrayName) != 0) &&
750       !(this->DoCopyAllOff && (this->GetFlag(arrayName) != 1)) && fd->GetAbstractArray(i))
751     {
752       this->AddArray(fd->GetAbstractArray(i));
753     }
754   }
755 }
756 
757 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)758 void vtkFieldData::PrintSelf(ostream& os, vtkIndent indent)
759 {
760   this->Superclass::PrintSelf(os, indent);
761 
762   os << indent << "Number Of Arrays: " << this->GetNumberOfArrays() << "\n";
763   for (int i = 0; i < this->GetNumberOfArrays(); i++)
764   {
765     if (this->GetArrayName(i))
766     {
767       os << indent << "Array " << i << " name = " << this->GetArrayName(i) << "\n";
768     }
769     else
770     {
771       os << indent << "Array " << i << " name = nullptr\n";
772     }
773   }
774   os << indent << "Number Of Components: " << this->GetNumberOfComponents() << "\n";
775   os << indent << "Number Of Tuples: " << this->GetNumberOfTuples() << "\n";
776 }
777 
778 //------------------------------------------------------------------------------
779 // Get the number of components in the field. This is determined by adding
780 // up the components in each non-nullptr array.
GetNumberOfComponents()781 int vtkFieldData::GetNumberOfComponents()
782 {
783   int i, numComp;
784 
785   for (i = numComp = 0; i < this->GetNumberOfArrays(); i++)
786   {
787     if (this->Data[i])
788     {
789       numComp += this->Data[i]->GetNumberOfComponents();
790     }
791   }
792 
793   return numComp;
794 }
795 
796 //------------------------------------------------------------------------------
797 // Get the number of tuples in the field.
GetNumberOfTuples()798 vtkIdType vtkFieldData::GetNumberOfTuples()
799 {
800   vtkAbstractArray* da;
801   if ((da = this->GetAbstractArray(0)))
802   {
803     return da->GetNumberOfTuples();
804   }
805   else
806   {
807     return 0;
808   }
809 }
810 
811 //------------------------------------------------------------------------------
812 // Set the number of tuples for each data array in the field.
SetNumberOfTuples(const vtkIdType number)813 void vtkFieldData::SetNumberOfTuples(const vtkIdType number)
814 {
815   for (int i = 0; i < this->GetNumberOfArrays(); i++)
816   {
817     this->Data[i]->SetNumberOfTuples(number);
818   }
819 }
820 
821 //------------------------------------------------------------------------------
822 // Set the jth tuple in source field data at the ith location.
823 // Set operations
824 // means that no range checking is performed, so they're faster.
SetTuple(const vtkIdType i,const vtkIdType j,vtkFieldData * source)825 void vtkFieldData::SetTuple(const vtkIdType i, const vtkIdType j, vtkFieldData* source)
826 {
827   for (int k = 0; k < this->GetNumberOfArrays(); k++)
828   {
829     this->Data[k]->SetTuple(i, j, source->Data[k]);
830   }
831 }
832 
833 //------------------------------------------------------------------------------
834 // Insert the tuple value at the ith location. Range checking is
835 // performed and memory allocates as necessary.
InsertTuple(const vtkIdType i,const vtkIdType j,vtkFieldData * source)836 void vtkFieldData::InsertTuple(const vtkIdType i, const vtkIdType j, vtkFieldData* source)
837 {
838   for (int k = 0; k < this->GetNumberOfArrays(); k++)
839   {
840     this->Data[k]->InsertTuple(i, j, source->GetAbstractArray(k));
841   }
842 }
843 
844 //------------------------------------------------------------------------------
845 // Insert the tuple value at the end of the tuple matrix. Range
846 // checking is performed and memory is allocated as necessary.
InsertNextTuple(const vtkIdType j,vtkFieldData * source)847 vtkIdType vtkFieldData::InsertNextTuple(const vtkIdType j, vtkFieldData* source)
848 {
849   vtkIdType id = this->GetNumberOfTuples();
850   this->InsertTuple(id, j, source);
851   return id;
852 }
853