VTK  9.1.0
vtkArrayListTemplate.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkArrayListTemplate.h
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 =========================================================================*/
45 #ifndef vtkArrayListTemplate_h
46 #define vtkArrayListTemplate_h
47 
48 #include "vtkDataArray.h"
49 #include "vtkDataSetAttributes.h"
50 #include "vtkSmartPointer.h"
51 #include "vtkStdString.h"
52 
53 #include <algorithm>
54 #include <vector>
55 
56 // Create a generic class supporting virtual dispatch to type-specific
57 // subclasses.
59 {
61  int NumComp;
63 
64  BaseArrayPair(vtkIdType num, int numComp, vtkDataArray* outArray)
65  : Num(num)
66  , NumComp(numComp)
67  , OutputArray(outArray)
68  {
69  }
70  virtual ~BaseArrayPair() = default;
71 
72  virtual void Copy(vtkIdType inId, vtkIdType outId) = 0;
73  virtual void Interpolate(
74  int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId) = 0;
75  virtual void Average(int numPts, const vtkIdType* ids, vtkIdType outId) = 0;
76  virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) = 0;
77  virtual void AssignNullValue(vtkIdType outId) = 0;
78  virtual void Realloc(vtkIdType sze) = 0;
79 };
80 
81 // Type specific interpolation on a matched pair of data arrays
82 template <typename T>
83 struct ArrayPair : public BaseArrayPair
84 {
85  T* Input;
86  T* Output;
88 
89  ArrayPair(T* in, T* out, vtkIdType num, int numComp, vtkDataArray* outArray, T null)
90  : BaseArrayPair(num, numComp, outArray)
91  , Input(in)
92  , Output(out)
93  , NullValue(null)
94  {
95  }
96  ~ArrayPair() override = default; // calm down some finicky compilers
97 
98  void Copy(vtkIdType inId, vtkIdType outId) override
99  {
100  for (int j = 0; j < this->NumComp; ++j)
101  {
102  this->Output[outId * this->NumComp + j] = this->Input[inId * this->NumComp + j];
103  }
104  }
105 
107  int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId) override
108  {
109  for (int j = 0; j < this->NumComp; ++j)
110  {
111  double v = 0.0;
112  for (vtkIdType i = 0; i < numWeights; ++i)
113  {
114  v += weights[i] * static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
115  }
116  this->Output[outId * this->NumComp + j] = static_cast<T>(v);
117  }
118  }
119 
120  void Average(int numPts, const vtkIdType* ids, vtkIdType outId) override
121  {
122  for (int j = 0; j < this->NumComp; ++j)
123  {
124  double v = 0.0;
125  for (vtkIdType i = 0; i < numPts; ++i)
126  {
127  v += static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
128  }
129  v /= static_cast<double>(numPts);
130  this->Output[outId * this->NumComp + j] = static_cast<T>(v);
131  }
132  }
133 
134  void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
135  {
136  double v;
137  vtkIdType numComp = this->NumComp;
138  for (int j = 0; j < numComp; ++j)
139  {
140  v = this->Input[v0 * numComp + j] +
141  t * (this->Input[v1 * numComp + j] - this->Input[v0 * numComp + j]);
142  this->Output[outId * numComp + j] = static_cast<T>(v);
143  }
144  }
145 
146  void AssignNullValue(vtkIdType outId) override
147  {
148  for (int j = 0; j < this->NumComp; ++j)
149  {
150  this->Output[outId * this->NumComp + j] = this->NullValue;
151  }
152  }
153 
154  void Realloc(vtkIdType sze) override
155  {
156  this->OutputArray->WriteVoidPointer(0, sze * this->NumComp);
157  this->Output = static_cast<T*>(this->OutputArray->GetVoidPointer(0));
158  }
159 };
160 
161 // Type specific interpolation on a pair of data arrays with different types, where the
162 // output type is expected to be a real type (i.e., float or double).
163 template <typename TInput, typename TOutput>
165 {
166  TInput* Input;
167  TOutput* Output;
168  TOutput NullValue;
169 
171  TInput* in, TOutput* out, vtkIdType num, int numComp, vtkDataArray* outArray, TOutput null)
172  : BaseArrayPair(num, numComp, outArray)
173  , Input(in)
174  , Output(out)
175  , NullValue(null)
176  {
177  }
178  ~RealArrayPair() override = default; // calm down some finicky compilers
179 
180  void Copy(vtkIdType inId, vtkIdType outId) override
181  {
182  for (int j = 0; j < this->NumComp; ++j)
183  {
184  this->Output[outId * this->NumComp + j] =
185  static_cast<TOutput>(this->Input[inId * this->NumComp + j]);
186  }
187  }
188 
190  int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId) override
191  {
192  for (int j = 0; j < this->NumComp; ++j)
193  {
194  double v = 0.0;
195  for (vtkIdType i = 0; i < numWeights; ++i)
196  {
197  v += weights[i] * static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
198  }
199  this->Output[outId * this->NumComp + j] = static_cast<TOutput>(v);
200  }
201  }
202 
203  void Average(int numPts, const vtkIdType* ids, vtkIdType outId) override
204  {
205  for (int j = 0; j < this->NumComp; ++j)
206  {
207  double v = 0.0;
208  for (vtkIdType i = 0; i < numPts; ++i)
209  {
210  v += static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
211  }
212  v /= static_cast<double>(numPts);
213  this->Output[outId * this->NumComp + j] = static_cast<TOutput>(v);
214  }
215  }
216 
217  void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
218  {
219  double v;
220  vtkIdType numComp = this->NumComp;
221  for (int j = 0; j < numComp; ++j)
222  {
223  v = this->Input[v0 * numComp + j] +
224  t * (this->Input[v1 * numComp + j] - this->Input[v0 * numComp + j]);
225  this->Output[outId * numComp + j] = static_cast<TOutput>(v);
226  }
227  }
228 
229  void AssignNullValue(vtkIdType outId) override
230  {
231  for (int j = 0; j < this->NumComp; ++j)
232  {
233  this->Output[outId * this->NumComp + j] = this->NullValue;
234  }
235  }
236 
237  void Realloc(vtkIdType sze) override
238  {
239  this->OutputArray->WriteVoidPointer(0, sze * this->NumComp);
240  this->Output = static_cast<TOutput*>(this->OutputArray->GetVoidPointer(0));
241  }
242 };
243 
244 // Forward declarations. This makes working with vtkTemplateMacro easier.
245 struct ArrayList;
246 
247 template <typename T>
249  ArrayList* list, T* inData, T* outData, vtkIdType numTuples, int numComp, T nullValue);
250 
251 // A list of the arrays to interpolate, and a method to invoke interpolation on the list
252 struct ArrayList
253 {
254  // The list of arrays, and the arrays not to process
255  std::vector<BaseArrayPair*> Arrays;
256  std::vector<vtkDataArray*> ExcludedArrays;
257 
258  // Add the arrays to interpolate here (from attribute data). Note that this method is
259  // not thread-safe due to its use of vtkDataSetAttributes.
261  double nullValue = 0.0, vtkTypeBool promote = true);
262 
263  // Add an array that interpolates from its own attribute values
265  vtkIdType numOutPts, vtkDataSetAttributes* attr, double nullValue = 0.0);
266 
267  // Add a pair of arrays (manual insertion). Returns the output array created,
268  // if any. No array may be created if \c inArray was previously marked as
269  // excluded using ExcludeArray().
270  vtkDataArray* AddArrayPair(vtkIdType numTuples, vtkDataArray* inArray, vtkStdString& outArrayName,
271  double nullValue, vtkTypeBool promote);
272 
273  // Any array excluded here is not added by AddArrays() or AddArrayPair, hence not
274  // processed. Also check whether an array is excluded.
277 
278  // Loop over the array pairs and copy data from one to another. This (and the following methods)
279  // can be used within threads.
280  void Copy(vtkIdType inId, vtkIdType outId)
281  {
282  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
283  {
284  (*it)->Copy(inId, outId);
285  }
286  }
287 
288  // Loop over the arrays and have them interpolate themselves
289  void Interpolate(int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId)
290  {
291  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
292  {
293  (*it)->Interpolate(numWeights, ids, weights, outId);
294  }
295  }
296 
297  // Loop over the arrays and have them averaged
298  void Average(int numPts, const vtkIdType* ids, vtkIdType outId)
299  {
300  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
301  {
302  (*it)->Average(numPts, ids, outId);
303  }
304  }
305 
306  // Loop over the arrays perform edge interpolation
307  void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
308  {
309  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
310  {
311  (*it)->InterpolateEdge(v0, v1, t, outId);
312  }
313  }
314 
315  // Loop over the arrays and assign the null value
317  {
318  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
319  {
320  (*it)->AssignNullValue(outId);
321  }
322  }
323 
324  // Extend (realloc) the arrays
325  void Realloc(vtkIdType sze)
326  {
327  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
328  {
329  (*it)->Realloc(sze);
330  }
331  }
332 
333  // Only you can prevent memory leaks!
335  {
336  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
337  {
338  delete (*it);
339  }
340  }
341 
342  // Return the number of arrays
343  vtkIdType GetNumberOfArrays() { return static_cast<vtkIdType>(Arrays.size()); }
344 };
345 
346 #include "vtkArrayListTemplate.txx"
347 
348 #endif
349 // VTK-HeaderTest-Exclude: vtkArrayListTemplate.h
virtual void * GetVoidPointer(vtkIdType valueIdx)=0
Return a void pointer.
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:50
virtual void * WriteVoidPointer(vtkIdType valueIdx, vtkIdType numValues)=0
Get the address of a particular data index.
represent and manipulate attribute data in a dataset
Wrapper around std::string to keep symbols short.
Definition: vtkStdString.h:36
void Average(int numPts, const vtkIdType *ids, vtkIdType outId)
void ExcludeArray(vtkDataArray *da)
std::vector< vtkDataArray * > ExcludedArrays
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
void AddSelfInterpolatingArrays(vtkIdType numOutPts, vtkDataSetAttributes *attr, double nullValue=0.0)
void AssignNullValue(vtkIdType outId)
vtkDataArray * AddArrayPair(vtkIdType numTuples, vtkDataArray *inArray, vtkStdString &outArrayName, double nullValue, vtkTypeBool promote)
vtkIdType GetNumberOfArrays()
void Copy(vtkIdType inId, vtkIdType outId)
void AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD, vtkDataSetAttributes *outPD, double nullValue=0.0, vtkTypeBool promote=true)
vtkTypeBool IsExcluded(vtkDataArray *da)
void Realloc(vtkIdType sze)
std::vector< BaseArrayPair * > Arrays
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId)
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
void AssignNullValue(vtkIdType outId) override
void Average(int numPts, const vtkIdType *ids, vtkIdType outId) override
~ArrayPair() override=default
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId) override
ArrayPair(T *in, T *out, vtkIdType num, int numComp, vtkDataArray *outArray, T null)
void Copy(vtkIdType inId, vtkIdType outId) override
void Realloc(vtkIdType sze) override
vtkSmartPointer< vtkDataArray > OutputArray
virtual void Average(int numPts, const vtkIdType *ids, vtkIdType outId)=0
virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)=0
virtual void AssignNullValue(vtkIdType outId)=0
virtual void Copy(vtkIdType inId, vtkIdType outId)=0
virtual ~BaseArrayPair()=default
virtual void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId)=0
virtual void Realloc(vtkIdType sze)=0
BaseArrayPair(vtkIdType num, int numComp, vtkDataArray *outArray)
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId) override
~RealArrayPair() override=default
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
void Copy(vtkIdType inId, vtkIdType outId) override
void AssignNullValue(vtkIdType outId) override
void Realloc(vtkIdType sze) override
RealArrayPair(TInput *in, TOutput *out, vtkIdType num, int numComp, vtkDataArray *outArray, TOutput null)
void Average(int numPts, const vtkIdType *ids, vtkIdType outId) override
int vtkTypeBool
Definition: vtkABI.h:69
void CreateArrayPair(ArrayList *list, T *inData, T *outData, vtkIdType numTuples, int numComp, T nullValue)
int vtkIdType
Definition: vtkType.h:332