VTK  9.2.6
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 "vtkAbstractArray.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, vtkAbstractArray* 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 WeightedAverage(
77  int numPts, const vtkIdType* ids, const double* weights, vtkIdType outId) = 0;
78  virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) = 0;
79  virtual void AssignNullValue(vtkIdType outId) = 0;
80  virtual void Realloc(vtkIdType sze) = 0;
81 };
82 
83 // Type specific interpolation on a matched pair of data arrays
84 template <typename T>
85 struct ArrayPair : public BaseArrayPair
86 {
87  T* Input;
88  T* Output;
90 
91  ArrayPair(T* in, T* out, vtkIdType num, int numComp, vtkAbstractArray* outArray, T null)
92  : BaseArrayPair(num, numComp, outArray)
93  , Input(in)
94  , Output(out)
95  , NullValue(null)
96  {
97  }
98  ~ArrayPair() override = default; // calm down some finicky compilers
99 
100  void Copy(vtkIdType inId, vtkIdType outId) override
101  {
102  for (int j = 0; j < this->NumComp; ++j)
103  {
104  this->Output[outId * this->NumComp + j] = this->Input[inId * this->NumComp + j];
105  }
106  }
107 
109  int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId) override
110  {
111  for (int j = 0; j < this->NumComp; ++j)
112  {
113  double v = 0.0;
114  for (vtkIdType i = 0; i < numWeights; ++i)
115  {
116  v += weights[i] * static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
117  }
118  this->Output[outId * this->NumComp + j] = static_cast<T>(v);
119  }
120  }
121 
122  void Average(int numPts, const vtkIdType* ids, vtkIdType outId) override
123  {
124  for (int j = 0; j < this->NumComp; ++j)
125  {
126  double v = 0.0;
127  for (vtkIdType i = 0; i < numPts; ++i)
128  {
129  v += static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
130  }
131  v /= static_cast<double>(numPts);
132  this->Output[outId * this->NumComp + j] = static_cast<T>(v);
133  }
134  }
135 
137  int numPts, const vtkIdType* ids, const double* weights, vtkIdType outId) override
138  {
139  for (int j = 0; j < this->NumComp; ++j)
140  {
141  double v = 0.0;
142  for (vtkIdType i = 0; i < numPts; ++i)
143  {
144  v += (weights[i] * static_cast<double>(this->Input[ids[i] * this->NumComp + j]));
145  }
146  this->Output[outId * this->NumComp + j] = static_cast<T>(v);
147  }
148  }
149 
150  void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
151  {
152  double v;
153  vtkIdType numComp = this->NumComp;
154  for (int j = 0; j < numComp; ++j)
155  {
156  v = this->Input[v0 * numComp + j] +
157  t * (this->Input[v1 * numComp + j] - this->Input[v0 * numComp + j]);
158  this->Output[outId * numComp + j] = static_cast<T>(v);
159  }
160  }
161 
162  void AssignNullValue(vtkIdType outId) override
163  {
164  for (int j = 0; j < this->NumComp; ++j)
165  {
166  this->Output[outId * this->NumComp + j] = this->NullValue;
167  }
168  }
169 
170  void Realloc(vtkIdType sze) override
171  {
172  this->OutputArray->Resize(sze);
173  this->OutputArray->SetNumberOfTuples(sze);
174  this->Output = static_cast<T*>(this->OutputArray->GetVoidPointer(0));
175  }
176 };
177 
178 // Type specific interpolation on a pair of data arrays with different types, where the
179 // output type is expected to be a real type (i.e., float or double).
180 template <typename TInput, typename TOutput>
182 {
183  TInput* Input;
184  TOutput* Output;
185  TOutput NullValue;
186 
188  TInput* in, TOutput* out, vtkIdType num, int numComp, vtkAbstractArray* outArray, TOutput null)
189  : BaseArrayPair(num, numComp, outArray)
190  , Input(in)
191  , Output(out)
192  , NullValue(null)
193  {
194  }
195  ~RealArrayPair() override = default; // calm down some finicky compilers
196 
197  void Copy(vtkIdType inId, vtkIdType outId) override
198  {
199  for (int j = 0; j < this->NumComp; ++j)
200  {
201  this->Output[outId * this->NumComp + j] =
202  static_cast<TOutput>(this->Input[inId * this->NumComp + j]);
203  }
204  }
205 
207  int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId) override
208  {
209  for (int j = 0; j < this->NumComp; ++j)
210  {
211  double v = 0.0;
212  for (vtkIdType i = 0; i < numWeights; ++i)
213  {
214  v += weights[i] * static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
215  }
216  this->Output[outId * this->NumComp + j] = static_cast<TOutput>(v);
217  }
218  }
219 
220  void Average(int numPts, const vtkIdType* ids, vtkIdType outId) override
221  {
222  for (int j = 0; j < this->NumComp; ++j)
223  {
224  double v = 0.0;
225  for (vtkIdType i = 0; i < numPts; ++i)
226  {
227  v += static_cast<double>(this->Input[ids[i] * this->NumComp + j]);
228  }
229  v /= static_cast<double>(numPts);
230  this->Output[outId * this->NumComp + j] = static_cast<TOutput>(v);
231  }
232  }
233 
235  int numPts, const vtkIdType* ids, const double* weights, vtkIdType outId) override
236  {
237  for (int j = 0; j < this->NumComp; ++j)
238  {
239  double v = 0.0;
240  for (vtkIdType i = 0; i < numPts; ++i)
241  {
242  v += (weights[i] * static_cast<double>(this->Input[ids[i] * this->NumComp + j]));
243  }
244  this->Output[outId * this->NumComp + j] = static_cast<TOutput>(v);
245  }
246  }
247 
248  void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
249  {
250  double v;
251  vtkIdType numComp = this->NumComp;
252  for (int j = 0; j < numComp; ++j)
253  {
254  v = this->Input[v0 * numComp + j] +
255  t * (this->Input[v1 * numComp + j] - this->Input[v0 * numComp + j]);
256  this->Output[outId * numComp + j] = static_cast<TOutput>(v);
257  }
258  }
259 
260  void AssignNullValue(vtkIdType outId) override
261  {
262  for (int j = 0; j < this->NumComp; ++j)
263  {
264  this->Output[outId * this->NumComp + j] = this->NullValue;
265  }
266  }
267 
268  void Realloc(vtkIdType sze) override
269  {
270  this->OutputArray->Resize(sze);
271  this->OutputArray->SetNumberOfTuples(sze);
272  this->Output = static_cast<TOutput*>(this->OutputArray->GetVoidPointer(0));
273  }
274 };
275 
276 // Forward declarations. This makes working with vtkTemplateMacro easier.
277 struct ArrayList;
278 
279 template <typename T>
280 void CreateArrayPair(
281  ArrayList* list, T* inData, T* outData, vtkIdType numTuples, int numComp, T nullValue);
282 
283 // A list of the arrays to interpolate, and a method to invoke interpolation on the list
284 struct ArrayList
285 {
286  // The list of arrays, and the arrays not to process
287  std::vector<BaseArrayPair*> Arrays;
288  std::vector<vtkAbstractArray*> ExcludedArrays;
289 
290  // Add the arrays to interpolate here (from attribute data). Note that this method is
291  // not thread-safe due to its use of vtkDataSetAttributes.
292  void AddArrays(vtkIdType numOutPts, vtkDataSetAttributes* inPD, vtkDataSetAttributes* outPD,
293  double nullValue = 0.0, vtkTypeBool promote = true);
294 
295  // Add an array that interpolates from its own attribute values
297  vtkIdType numOutPts, vtkDataSetAttributes* attr, double nullValue = 0.0);
298 
299  // Add a pair of arrays (manual insertion). Returns the output array created,
300  // if any. No array may be created if \c inArray was previously marked as
301  // excluded using ExcludeArray().
303  vtkStdString& outArrayName, double nullValue, vtkTypeBool promote);
304 
305  // Any array excluded here is not added by AddArrays() or AddArrayPair, hence not
306  // processed. Also check whether an array is excluded.
307  void ExcludeArray(vtkAbstractArray* da);
309 
310  // Loop over the array pairs and copy data from one to another. This (and the following methods)
311  // can be used within threads.
312  void Copy(vtkIdType inId, vtkIdType outId)
313  {
314  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
315  {
316  (*it)->Copy(inId, outId);
317  }
318  }
319 
320  // Loop over the arrays and have them interpolate themselves
321  void Interpolate(int numWeights, const vtkIdType* ids, const double* weights, vtkIdType outId)
322  {
323  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
324  {
325  (*it)->Interpolate(numWeights, ids, weights, outId);
326  }
327  }
328 
329  // Loop over the arrays and have them averaged
330  void Average(int numPts, const vtkIdType* ids, vtkIdType outId)
331  {
332  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
333  {
334  (*it)->Average(numPts, ids, outId);
335  }
336  }
337 
338  // Loop over the arrays and weighted average the attributes. The weights should sum to 1.0.
339  void WeightedAverage(int numPts, const vtkIdType* ids, const double* weights, vtkIdType outId)
340  {
341  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
342  {
343  (*it)->WeightedAverage(numPts, ids, weights, outId);
344  }
345  }
346 
347  // Loop over the arrays perform edge interpolation
348  void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
349  {
350  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
351  {
352  (*it)->InterpolateEdge(v0, v1, t, outId);
353  }
354  }
355 
356  // Loop over the arrays and assign the null value
358  {
359  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
360  {
361  (*it)->AssignNullValue(outId);
362  }
363  }
364 
365  // Extend (realloc) the arrays
366  void Realloc(vtkIdType sze)
367  {
368  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
369  {
370  (*it)->Realloc(sze);
371  }
372  }
373 
374  // Only you can prevent memory leaks!
376  {
377  for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin(); it != Arrays.end(); ++it)
378  {
379  delete (*it);
380  }
381  }
382 
383  // Return the number of arrays
384  vtkIdType GetNumberOfArrays() { return static_cast<vtkIdType>(Arrays.size()); }
385 };
386 
387 #include "vtkArrayListTemplate.txx"
388 
389 #endif
390 // VTK-HeaderTest-Exclude: vtkArrayListTemplate.h
vtkSmartPointer< vtkAbstractArray > OutputArray
Wrapper around std::string to keep symbols short.
Definition: vtkStdString.h:38
std::vector< BaseArrayPair * > Arrays
void ExcludeArray(vtkAbstractArray *da)
void WeightedAverage(int numPts, const vtkIdType *ids, const double *weights, vtkIdType outId) override
std::vector< vtkAbstractArray * > ExcludedArrays
virtual void * GetVoidPointer(vtkIdType valueIdx)=0
Return a void pointer.
vtkAbstractArray * AddArrayPair(vtkIdType numTuples, vtkAbstractArray *inArray, vtkStdString &outArrayName, double nullValue, vtkTypeBool promote)
~RealArrayPair() override=default
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
void Copy(vtkIdType inId, vtkIdType outId) override
void WeightedAverage(int numPts, const vtkIdType *ids, const double *weights, vtkIdType outId) override
Abstract superclass for all arrays.
void Copy(vtkIdType inId, vtkIdType outId) override
void AssignNullValue(vtkIdType outId) override
void Realloc(vtkIdType sze) override
void Average(int numPts, const vtkIdType *ids, vtkIdType outId)
virtual void Average(int numPts, const vtkIdType *ids, vtkIdType outId)=0
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId) override
int vtkIdType
Definition: vtkType.h:332
void AssignNullValue(vtkIdType outId) override
virtual void Realloc(vtkIdType sze)=0
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId)
virtual void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId)=0
virtual void WeightedAverage(int numPts, const vtkIdType *ids, const double *weights, vtkIdType outId)=0
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
int vtkTypeBool
Definition: vtkABI.h:69
void AssignNullValue(vtkIdType outId)
RealArrayPair(TInput *in, TOutput *out, vtkIdType num, int numComp, vtkAbstractArray *outArray, TOutput null)
vtkIdType GetNumberOfArrays()
void Copy(vtkIdType inId, vtkIdType outId)
~ArrayPair() override=default
void Realloc(vtkIdType sze)
void AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD, vtkDataSetAttributes *outPD, double nullValue=0.0, vtkTypeBool promote=true)
represent and manipulate attribute data in a dataset
virtual void Copy(vtkIdType inId, vtkIdType outId)=0
vtkTypeBool IsExcluded(vtkAbstractArray *da)
virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)=0
virtual vtkTypeBool Resize(vtkIdType numTuples)=0
Resize the array to the requested number of tuples and preserve data.
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId) override
void Average(int numPts, const vtkIdType *ids, vtkIdType outId) override
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) override
void Realloc(vtkIdType sze) override
BaseArrayPair(vtkIdType num, int numComp, vtkAbstractArray *outArray)
void CreateArrayPair(ArrayList *list, T *inData, T *outData, vtkIdType numTuples, int numComp, T nullValue)
virtual void SetNumberOfTuples(vtkIdType numTuples)=0
Set the number of tuples (a component group) in the array.
ArrayPair(T *in, T *out, vtkIdType num, int numComp, vtkAbstractArray *outArray, T null)
virtual void AssignNullValue(vtkIdType outId)=0
void Average(int numPts, const vtkIdType *ids, vtkIdType outId) override
void WeightedAverage(int numPts, const vtkIdType *ids, const double *weights, vtkIdType outId)
void AddSelfInterpolatingArrays(vtkIdType numOutPts, vtkDataSetAttributes *attr, double nullValue=0.0)
virtual ~BaseArrayPair()=default