1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkArrayListTemplate.txx
5 
6   Copyright (c) Kitware, Inc.
7   All rights reserved.
8   See LICENSE file 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 "vtkArrayListTemplate.h"
16 #include "vtkFloatArray.h"
17 
18 #include <cassert>
19 
20 #ifndef vtkArrayListTemplate_txx
21 #define vtkArrayListTemplate_txx
22 
23 //----------------------------------------------------------------------------
24 // Sort of a little object factory (in conjunction w/ vtkTemplateMacro())
25 template <typename T>
CreateArrayPair(ArrayList * list,T * inData,T * outData,vtkIdType numTuples,int numComp,vtkDataArray * outArray,T nullValue)26 void CreateArrayPair(ArrayList *list, T *inData, T *outData,
27                      vtkIdType numTuples, int numComp, vtkDataArray *outArray,
28                      T nullValue)
29 {
30   ArrayPair<T> *pair = new ArrayPair<T>(inData,outData,numTuples,numComp,
31                                         outArray,nullValue);
32   list->Arrays.push_back(pair);
33 }
34 
35 //----------------------------------------------------------------------------
36 // Sort of a little object factory (in conjunction w/ vtkTemplateMacro())
37 template <typename T>
CreateRealArrayPair(ArrayList * list,T * inData,float * outData,vtkIdType numTuples,int numComp,vtkDataArray * outArray,float nullValue)38 void CreateRealArrayPair(ArrayList *list, T *inData, float *outData,
39                          vtkIdType numTuples, int numComp, vtkDataArray *outArray,
40                          float nullValue)
41 {
42   RealArrayPair<T,float> *pair =
43     new RealArrayPair<T,float>(inData,outData,numTuples,numComp,
44                                outArray,nullValue);
45   list->Arrays.push_back(pair);
46 }
47 
48 //----------------------------------------------------------------------------
49 // Indicate arrays not to process
50 inline void ArrayList::
ExcludeArray(vtkDataArray * da)51 ExcludeArray(vtkDataArray *da)
52 {
53   ExcludedArrays.push_back(da);
54 }
55 
56 //----------------------------------------------------------------------------
57 // Has the specified array been excluded?
58 inline vtkTypeBool ArrayList::
IsExcluded(vtkDataArray * da)59 IsExcluded(vtkDataArray *da)
60 {
61   return (std::find(ExcludedArrays.begin(), ExcludedArrays.end(), da) != ExcludedArrays.end());
62 }
63 
64 //----------------------------------------------------------------------------
65 // Add an array pair (input,output) using the name provided for the output. The
66 // numTuples is the number of output tuples allocated.
67 inline vtkDataArray* ArrayList::
AddArrayPair(vtkIdType numTuples,vtkDataArray * inArray,vtkStdString & outArrayName,double nullValue,vtkTypeBool promote)68 AddArrayPair(vtkIdType numTuples, vtkDataArray *inArray,
69              vtkStdString &outArrayName, double nullValue, vtkTypeBool promote)
70 {
71   if (this->IsExcluded(inArray))
72   {
73     return nullptr;
74   }
75 
76   int iType = inArray->GetDataType();
77   vtkDataArray *outArray;
78   if ( promote && iType != VTK_FLOAT && iType != VTK_DOUBLE )
79   {
80     outArray = vtkFloatArray::New();
81     outArray->SetNumberOfComponents(inArray->GetNumberOfComponents());
82     outArray->SetNumberOfTuples(numTuples);
83     outArray->SetName(outArrayName);
84     void *iD = inArray->GetVoidPointer(0);
85     void *oD = outArray->GetVoidPointer(0);
86     switch (iType)
87     {
88       vtkTemplateMacro(CreateRealArrayPair(this, static_cast<VTK_TT *>(iD),
89                        static_cast<float*>(oD),numTuples,inArray->GetNumberOfComponents(),
90                        outArray,static_cast<float>(nullValue)));
91     }//over all VTK types
92   }
93   else
94   {
95     outArray = inArray->NewInstance();
96     outArray->SetNumberOfComponents(inArray->GetNumberOfComponents());
97     outArray->SetNumberOfTuples(numTuples);
98     outArray->SetName(outArrayName);
99     void *iD = inArray->GetVoidPointer(0);
100     void *oD = outArray->GetVoidPointer(0);
101     switch (iType)
102     {
103       vtkTemplateMacro(CreateArrayPair(this, static_cast<VTK_TT *>(iD),
104                        static_cast<VTK_TT *>(oD),numTuples,inArray->GetNumberOfComponents(),
105                        outArray,static_cast<VTK_TT>(nullValue)));
106     }//over all VTK types
107   }//promote integral types
108 
109   assert(outArray->GetReferenceCount() > 1);
110   outArray->FastDelete();
111   return outArray;
112 }
113 
114 //----------------------------------------------------------------------------
115 // Add the arrays to interpolate here. This presumes that vtkDataSetAttributes::CopyData() or
116 // vtkDataSetAttributes::InterpolateData() has been called, and the input and output array
117 // names match.
118 inline void ArrayList::
AddArrays(vtkIdType numOutPts,vtkDataSetAttributes * inPD,vtkDataSetAttributes * outPD,double nullValue,vtkTypeBool promote)119 AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD, vtkDataSetAttributes *outPD,
120           double nullValue, vtkTypeBool promote)
121 {
122   // Build the vector of interpolation pairs. Note that InterpolateAllocate should have
123   // been called at this point (output arrays created and allocated).
124   char *name;
125   vtkDataArray *iArray, *oArray;
126   int iType, oType;
127   void *iD, *oD;
128   int iNumComp, oNumComp;
129   int i, numArrays = outPD->GetNumberOfArrays();
130 
131   for (i=0; i < numArrays; ++i)
132   {
133     oArray = outPD->GetArray(i);
134     if ( oArray && ! this->IsExcluded(oArray) )
135     {
136       name = oArray->GetName();
137       iArray = inPD->GetArray(name);
138       if ( iArray && ! this->IsExcluded(iArray) )
139       {
140         iType = iArray->GetDataType();
141         oType = oArray->GetDataType();
142         iNumComp = iArray->GetNumberOfComponents();
143         oNumComp = oArray->GetNumberOfComponents();
144         if ( promote && oType != VTK_FLOAT && oType != VTK_DOUBLE )
145         {
146           oType = VTK_FLOAT;
147           vtkFloatArray *fArray = vtkFloatArray::New();
148           fArray->SetName(oArray->GetName());
149           fArray->SetNumberOfComponents(oNumComp);
150           outPD->AddArray(fArray); //nasty side effect will replace current array in the same spot
151           oArray = fArray;
152           fArray->Delete();
153         }
154         oArray->SetNumberOfTuples(numOutPts);
155 
156         assert( iNumComp == oNumComp );
157         if ( iType == oType )
158         {
159           iD = iArray->GetVoidPointer(0);
160           oD = oArray->GetVoidPointer(0);
161           switch (iType)
162           {
163             vtkTemplateMacro(CreateArrayPair(this, static_cast<VTK_TT *>(iD),
164                              static_cast<VTK_TT *>(oD),numOutPts,oNumComp,
165                              oArray,static_cast<VTK_TT>(nullValue)));
166           }//over all VTK types
167         }//if matching types
168         else //promoted type
169         {
170           iD = iArray->GetVoidPointer(0);
171           oD = oArray->GetVoidPointer(0);
172           switch (iType)
173           {
174             vtkTemplateMacro(CreateRealArrayPair(this, static_cast<VTK_TT *>(iD),
175                              static_cast<float*>(oD),numOutPts,iNumComp,
176                              oArray,static_cast<float>(nullValue)));
177           }//over all VTK types
178         }//if promoted pair
179       }//if matching input array
180     }//if output array
181   }//for each candidate array
182 }
183 
184 //----------------------------------------------------------------------------
185 // Add the arrays to interpolate here. This presumes that vtkDataSetAttributes::CopyData() or
186 // vtkDataSetAttributes::InterpolateData() has been called. This special version creates an
187 // array pair that interpolates from itself.
188 inline void ArrayList::
AddSelfInterpolatingArrays(vtkIdType numOutPts,vtkDataSetAttributes * attr,double nullValue)189 AddSelfInterpolatingArrays(vtkIdType numOutPts, vtkDataSetAttributes *attr, double nullValue)
190 {
191   // Build the vector of interpolation pairs. Note that CopyAllocate/InterpolateAllocate should have
192   // been called at this point (output arrays created and allocated).
193   vtkDataArray *iArray;
194   int iType, iNumComp;
195   void *iD;
196   int i, numArrays = attr->GetNumberOfArrays();
197 
198   for (i=0; i < numArrays; ++i)
199   {
200     iArray = attr->GetArray(i);
201     if ( iArray && ! this->IsExcluded(iArray) )
202     {
203       iType = iArray->GetDataType();
204       iNumComp = iArray->GetNumberOfComponents();
205       iArray->WriteVoidPointer(0,numOutPts*iNumComp); //allocates memory, preserves data
206       iD = iArray->GetVoidPointer(0);
207       switch (iType)
208       {
209         vtkTemplateMacro(CreateArrayPair(this, static_cast<VTK_TT *>(iD),
210                          static_cast<VTK_TT *>(iD),numOutPts,iNumComp,
211                          iArray,static_cast<VTK_TT>(nullValue)));
212       }//over all VTK types
213     }//if not excluded
214   }//for each candidate array
215 }
216 
217 #endif
218