1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkDataArrayTemplate.h
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 // .NAME vtkDataArrayTemplate - Implementation template for vtkDataArray.
16 // .SECTION Description
17 // There is a vtkDataArray subclass for each native type supported by
18 // VTK.  This template is used to implement all the subclasses in the
19 // same way while avoiding code duplication.
20 
21 #ifndef vtkDataArrayTemplate_h
22 #define vtkDataArrayTemplate_h
23 
24 #include "vtkCommonCoreModule.h" // For export macro
25 #include "vtkTypedDataArray.h"
26 #include "vtkTypeTemplate.h" // For templated vtkObject API
27 #include <cassert> // for assert()
28 
29 template <class T>
30 class vtkDataArrayTemplateLookup;
31 
32 template <class T>
33 class VTKCOMMONCORE_EXPORT vtkDataArrayTemplate:
34     public vtkTypeTemplate<vtkDataArrayTemplate<T>, vtkTypedDataArray<T> >
35 {
36 public:
37   typedef vtkTypedDataArray<T> Superclass;
38   typedef typename Superclass::ValueType ValueType;
39   friend class vtkDataArrayTemplateHelper;
40 
41   void PrintSelf(ostream& os, vtkIndent indent);
42 
43   // Description:
44   // Typedef to a suitable iterator class.
45   // Rather than using this member directly, consider using
46   // vtkDataArrayIteratorMacro for safety and efficiency.
47   typedef ValueType* Iterator;
48 
49   // Description:
50   // Return an iterator initialized to the first element of the data.
51   // Rather than using this member directly, consider using
52   // vtkDataArrayIteratorMacro for safety and efficiency.
Begin()53   Iterator Begin() { return Iterator(this->GetVoidPointer(0)); }
54 
55   // Description:
56   // Return an iterator initialized to first element past the end of the data.
57   // Rather than using this member directly, consider using
58   // vtkDataArrayIteratorMacro for safety and efficiency.
End()59   Iterator End() { return Iterator(this->GetVoidPointer(this->MaxId + 1)); }
60 
61   // Description:
62   // Perform a fast, safe cast from a vtkAbstractArray to a
63   // vtkDataArrayTemplate.
64   // This method checks if:
65   // - source->GetArrayType() is appropriate, and
66   // - source->GetDataType() matches vtkTypeTraits<ValueType>::VTK_TYPE_ID
67   // if these conditions are met, the method performs a static_cast to return
68   // source as a vtkTypedDataArray pointer. Otherwise, NULL is returned.
69   static vtkDataArrayTemplate<T>* FastDownCast(vtkAbstractArray *src);
70 
71   // Description:
72   // Allocate memory for this array. Delete old storage only if necessary.
73   // Note that ext is no longer used.
74   int Allocate(vtkIdType sz, vtkIdType ext=1000);
75 
76   // Description:
77   // Release storage and reset array to initial state.
78   void Initialize();
79 
80   // Description:
81   // Return the size of the data type.
GetDataTypeSize()82   int GetDataTypeSize() { return static_cast<int>(sizeof(T)); }
83 
84   // Description:
85   // Set the number of n-tuples in the array.
86   void SetNumberOfTuples(vtkIdType number);
87 
88   // Description:
89   // Set the tuple at the ith location using the jth tuple in the source array.
90   // This method assumes that the two arrays have the same type
91   // and structure. Note that range checking and memory allocation is not
92   // performed; use in conjunction with SetNumberOfTuples() to allocate space.
93   virtual void SetTuple(vtkIdType i, vtkIdType j, vtkAbstractArray* source);
94 
95   // Description:
96   // Insert the jth tuple in the source array, at ith location in this array.
97   // Note that memory allocation is performed as necessary to hold the data.
98   virtual void InsertTuple(vtkIdType i, vtkIdType j, vtkAbstractArray* source);
99 
100   // Description:
101   // Copy the tuples indexed in srcIds from the source array to the tuple
102   // locations indexed by dstIds in this array.
103   // Note that memory allocation is performed as necessary to hold the data.
104   virtual void InsertTuples(vtkIdList *destIds, vtkIdList *srcIds,
105                             vtkAbstractArray *source);
106 
107   // Description:
108   // Copy n consecutive tuples starting at srcStart from the source array to
109   // this array, starting at the dstStart location.
110   // Note that memory allocation is performed as necessary to hold the data.
111   virtual void InsertTuples(vtkIdType dstStart, vtkIdType n, vtkIdType srcStart,
112                             vtkAbstractArray* source);
113 
114   // Description:
115   // Insert the jth tuple in the source array, at the end in this array.
116   // Note that memory allocation is performed as necessary to hold the data.
117   // Returns the location at which the data was inserted.
118   virtual vtkIdType InsertNextTuple(vtkIdType j, vtkAbstractArray* source);
119 
120   // Description:
121   // Get a pointer to a tuple at the ith location. This is a dangerous method
122   // (it is not thread safe since a pointer is returned).
123   double* GetTuple(vtkIdType i);
124 
125   // Description:
126   // Copy the tuple value into a user-provided array.
127   void GetTuple(vtkIdType i, double* tuple);
128   void GetTupleValue(vtkIdType i, T* tuple);
129 
130   // Description:
131   // Set the tuple value at the ith location in the array.
132   void SetTuple(vtkIdType i, const float* tuple);
133   void SetTuple(vtkIdType i, const double* tuple);
134   void SetTupleValue(vtkIdType i, const T* tuple);
135 
136   // Description:
137   // Insert (memory allocation performed) the tuple into the ith location
138   // in the array.
139   void InsertTuple(vtkIdType i, const float* tuple);
140   void InsertTuple(vtkIdType i, const double* tuple);
141   void InsertTupleValue(vtkIdType i, const T* tuple);
142 
143   // Description:
144   // Insert (memory allocation performed) the tuple onto the end of the array.
145   vtkIdType InsertNextTuple(const float* tuple);
146   vtkIdType InsertNextTuple(const double* tuple);
147   vtkIdType InsertNextTupleValue(const T* tuple);
148 
149   // Description:
150   // Get the range of array values for the given component in the
151   // native data type.
GetValueRange(T range[2],int comp)152   void GetValueRange(T range[2], int comp)
153     {
154     double doubleRange[2];
155     this->ComputeRange(doubleRange, comp);
156     range[0] = static_cast<T>(doubleRange[0]);
157     range[1] = static_cast<T>(doubleRange[1]);
158     }
GetValueRange(int comp)159   T *GetValueRange(int comp)
160     {
161     this->GetValueRange(this->ValueRange, comp);
162     return this->ValueRange;
163     }
164 
165   // Description:
166   // Get the range of array values for the 0th component in the
167   // native data type.
GetValueRange()168   T *GetValueRange()
169     { return this->GetValueRange(0); }
GetValueRange(T range[2])170   void GetValueRange(T range[2])
171     { this->GetValueRange(range, 0); }
172 
173   // Description:
174   // Resize object to just fit data requirement. Reclaims extra memory.
Squeeze()175   void Squeeze() { this->ResizeAndExtend (this->MaxId+1); }
176 
177   // Description:
178   // Return the capacity in typeof T units of the current array.
Capacity()179   vtkIdType Capacity() { return this->Size; }
180 
181   // Description:
182   // Resize the array while conserving the data.
183   // Caution: No assumption can be made on the resulting size of the DataArray,
184   //          meaning that the provided argument won't necessary be equal to
185   //          the data array size, but at least the size will be bigger.
186   virtual int Resize(vtkIdType numTuples);
187 
188   // Description:
189   // Get the data at a particular index.
GetValue(vtkIdType id)190   T GetValue(vtkIdType id)
191     { assert(id >= 0 && id < this->Size); return this->Array[id]; }
GetValueReference(vtkIdType id)192   T& GetValueReference(vtkIdType id)
193     { assert(id >= 0 && id < this->Size); return this->Array[id]; }
194 
195   // Description:
196   // Set the data at a particular index. Does not do range checking. Make sure
197   // you use the method SetNumberOfValues() before inserting data.
SetValue(vtkIdType id,T value)198   void SetValue(vtkIdType id, T value)
199     { assert(id >= 0 && id < this->Size); this->Array[id] = value;};
200 
201   // Description:
202   // Specify the number of values for this object to hold. Does an
203   // allocation as well as setting the MaxId ivar. Used in conjunction with
204   // SetValue() method for fast insertion.
205   void SetNumberOfValues(vtkIdType number);
206 
207   // Description:
208   // Insert data at a specified position in the array.
209   void InsertValue(vtkIdType id, T f);
210 
211   // Description:
212   // Set a value in the array from a vtkVariant.
213   void SetVariantValue(vtkIdType id, vtkVariant value);
214 
215   // Description:
216   // Insert data at the end of the array. Return its location in the array.
217   vtkIdType InsertNextValue(T f);
218 
219   // Description:
220   // These methods remove tuples from the data array. They shift data and
221   // resize array, so the data array is still valid after this operation. Note,
222   // this operation is fairly slow.
223   virtual void RemoveTuple(vtkIdType id);
224   virtual void RemoveFirstTuple();
225   virtual void RemoveLastTuple();
226 
227   // Description:
228   // Return the data component at the ith tuple and jth component location.
229   // Note that i is less then NumberOfTuples and j is less then
230   // NumberOfComponents.
231   double GetComponent(vtkIdType i, int j);
232 
233   // Description:
234   // Set the data component at the ith tuple and jth component location.
235   // Note that i is less then NumberOfTuples and j is less then
236   // NumberOfComponents. Make sure enough memory has been allocated
237   // (use SetNumberOfTuples() and SetNumberOfComponents()).
238   void SetComponent(vtkIdType i, int j, double c);
239 
240   // Description:
241   // Insert the data component at ith tuple and jth component location.
242   // Note that memory allocation is performed as necessary to hold the data.
243   virtual void InsertComponent(vtkIdType i, int j, double c);
244 
245   // Description:
246   // Get the address of a particular data index. Make sure data is allocated
247   // for the number of items requested. Set MaxId according to the number of
248   // data values requested.
249   T* WritePointer(vtkIdType id, vtkIdType number);
WriteVoidPointer(vtkIdType id,vtkIdType number)250   virtual void* WriteVoidPointer(vtkIdType id, vtkIdType number)
251     { return this->WritePointer(id, number); }
252 
253   // Description:
254   // Get the address of a particular data index. Performs no checks
255   // to verify that the memory has been allocated etc.
256   // If the data is simply being iterated over, consider using
257   // vtkDataArrayIteratorMacro for safety and efficiency, rather than using this
258   // member directly.
GetPointer(vtkIdType id)259   T* GetPointer(vtkIdType id) { return this->Array + id; }
GetVoidPointer(vtkIdType id)260   virtual void* GetVoidPointer(vtkIdType id) { return this->GetPointer(id); }
261 
262 //BTX
263   enum DeleteMethod
264   {
265     VTK_DATA_ARRAY_FREE,
266     VTK_DATA_ARRAY_DELETE
267   };
268 //ETX
269 
270   // Description:
271   // This method lets the user specify data to be held by the array.  The
272   // array argument is a pointer to the data.  size is the size of the
273   // array supplied by the user.  Set save to 1 to keep the class from
274   // deleting the array when it cleans up or reallocates memory.  The class
275   // uses the actual array provided; it does not copy the data from the
276   // suppled array. If specified, the delete method determines how the data
277   // array will be deallocated. If the delete method is
278   // VTK_DATA_ARRAY_FREE, free() will be used. If the delete method is
279   // DELETE, delete[] will be used. The default is FREE.
280   void SetArray(T* array, vtkIdType size, int save, int deleteMethod);
SetArray(T * array,vtkIdType size,int save)281   void SetArray(T* array, vtkIdType size, int save)
282     { this->SetArray(array, size, save, VTK_DATA_ARRAY_FREE); }
SetVoidArray(void * array,vtkIdType size,int save)283   virtual void SetVoidArray(void* array, vtkIdType size, int save)
284     { this->SetArray(static_cast<T*>(array), size, save); }
SetVoidArray(void * array,vtkIdType size,int save,int deleteMethod)285   virtual void SetVoidArray(void* array,
286                             vtkIdType size,
287                             int save,
288                             int deleteMethod)
289     {
290       this->SetArray(static_cast<T*>(array), size, save, deleteMethod);
291     }
292 
293   // Description:
294   // This method copies the array data to the void pointer specified
295   // by the user.  It is up to the user to allocate enough memory for
296   // the void pointer.
297   virtual void ExportToVoidPointer(void *out_ptr);
298 
299   // Description:
300   // Returns a vtkArrayIteratorTemplate<T>.
301   virtual vtkArrayIterator* NewIterator();
302 
303   // Description:
304   // Return the indices where a specific value appears.
305   virtual vtkIdType LookupValue(vtkVariant value);
306   virtual void LookupValue(vtkVariant value, vtkIdList* ids);
307   vtkIdType LookupValue(T value);
308   void LookupValue(T value, vtkIdList* ids);
LookupTypedValue(T value)309   vtkIdType LookupTypedValue(T value)
310     { return this->LookupValue(value); }
LookupTypedValue(T value,vtkIdList * ids)311   void LookupTypedValue(T value, vtkIdList* ids)
312     { this->LookupValue(value, ids); }
313 
314   // Description:
315   // Tell the array explicitly that the data has changed.
316   // This is only necessary to call when you modify the array contents
317   // without using the array's API (i.e. you retrieve a pointer to the
318   // data and modify the array contents).  You need to call this so that
319   // the fast lookup will know to rebuild itself.  Otherwise, the lookup
320   // functions will give incorrect results.
321   virtual void DataChanged();
322 
323   // Description:
324   // Tell the array explicitly that a single data element has
325   // changed. Like DataChanged(), then is only necessary when you
326   // modify the array contents without using the array's API.
327   virtual void DataElementChanged(vtkIdType id);
328 
329   // Description:
330   // Delete the associated fast lookup data structure on this array,
331   // if it exists.  The lookup will be rebuilt on the next call to a lookup
332   // function.
333   virtual void ClearLookup();
334 
335   // Description:
336   // Method for type-checking in FastDownCast implementations.
GetArrayType()337   virtual int GetArrayType() { return vtkAbstractArray::DataArrayTemplate; }
338 
339 protected:
340   vtkDataArrayTemplate();
341   ~vtkDataArrayTemplate();
342 
343   T* Array;   // pointer to data
344   T ValueRange[2]; // range of the data
345   T* ResizeAndExtend(vtkIdType sz);  // function to resize data
346   T* Realloc(vtkIdType sz);
347 
348   int TupleSize; //used for data conversion
349   double* Tuple;
350 
351   int SaveUserArray;
352   int DeleteMethod;
353 
354   virtual bool ComputeScalarRange(double* ranges);
355   virtual bool ComputeVectorRange(double range[2]);
356 private:
357   vtkDataArrayTemplate(const vtkDataArrayTemplate&);  // Not implemented.
358   void operator=(const vtkDataArrayTemplate&);  // Not implemented.
359 
360   vtkDataArrayTemplateLookup<T>* Lookup;
361   bool RebuildLookup;
362   void UpdateLookup();
363 
364   void DeleteArray();
365 };
366 
367 #if !defined(VTK_NO_EXPLICIT_TEMPLATE_INSTANTIATION)
368 # define VTK_DATA_ARRAY_TEMPLATE_INSTANTIATE(T) \
369    template class VTKCOMMONCORE_EXPORT vtkDataArrayTemplate< T >
370 #else
371 # include "vtkDataArrayTemplateImplicit.txx"
372 # define VTK_DATA_ARRAY_TEMPLATE_INSTANTIATE(T)
373 #endif
374 
375 // This macro is used by the subclasses to create dummy
376 // declarations for these functions such that the wrapper
377 // can see them. The wrappers ignore vtkDataArrayTemplate.
378 #define vtkCreateWrappedArrayInterface(T) \
379   int GetDataType(); \
380   void GetTupleValue(vtkIdType i, T* tuple); \
381   void SetTupleValue(vtkIdType i, const T* tuple); \
382   void InsertTupleValue(vtkIdType i, const T* tuple); \
383   vtkIdType InsertNextTupleValue(const T* tuple); \
384   T GetValue(vtkIdType id); \
385   void SetValue(vtkIdType id, T value); \
386   void SetNumberOfValues(vtkIdType number); \
387   void InsertValue(vtkIdType id, T f); \
388   vtkIdType InsertNextValue(T f); \
389   T *GetValueRange(int comp); \
390   T *GetValueRange(); \
391   T* WritePointer(vtkIdType id, vtkIdType number); \
392   T* GetPointer(vtkIdType id)/*; \
393 
394   * These methods are not wrapped to avoid wrappers exposing these
395   * easy-to-get-wrong methods because passing in the wrong value for 'save' is
396   * guaranteed to cause a memory issue down the line. Either the wrappers
397   * didn't use malloc to allocate the memory or the memory isn't actually
398   * persisted because a temporary array is used that doesn't persist like this
399   * method expects.
400 
401   void SetArray(T* array, vtkIdType size, int save); \
402   void SetArray(T* array, vtkIdType size, int save, int deleteMethod) */
403 
404 #endif // !defined(vtkDataArrayTemplate_h)
405 
406 // This portion must be OUTSIDE the include blockers.  Each
407 // vtkDataArray subclass uses this to give its instantiation of this
408 // template a DLL interface.
409 #if defined(VTK_DATA_ARRAY_TEMPLATE_TYPE) && !defined(VTK_NO_EXPLICIT_TEMPLATE_INSTANTIATION)
410 # if defined(VTK_BUILD_SHARED_LIBS) && defined(_MSC_VER)
411 #  pragma warning (push)
412 #  pragma warning (disable: 4091) // warning C4091: 'extern ' :
413    // ignored on left of 'int' when no variable is declared
414 #  pragma warning (disable: 4231) // Compiler-specific extension warning.
415 
416    // We need to disable warning 4910 and do an extern dllexport
417    // anyway.  When deriving vtkCharArray and other types from an
418    // instantiation of this template the compiler does an explicit
419    // instantiation of the base class.  From outside the vtkCommon
420    // library we block this using an extern dllimport instantiation.
421    // For classes inside vtkCommon we should be able to just do an
422    // extern instantiation, but VS 2008 complains about missing
423    // definitions.  We cannot do an extern dllimport inside vtkCommon
424    // since the symbols are local to the dll.  An extern dllexport
425    // seems to be the only way to convince VS 2008 to do the right
426    // thing, so we just disable the warning.
427 #  pragma warning (disable: 4910) // extern and dllexport incompatible
428 
429    // Use an "extern explicit instantiation" to give the class a DLL
430    // interface.  This is a compiler-specific extension.
431    extern VTK_DATA_ARRAY_TEMPLATE_INSTANTIATE(VTK_DATA_ARRAY_TEMPLATE_TYPE);
432 #  pragma warning (pop)
433 # endif
434 # undef VTK_DATA_ARRAY_TEMPLATE_TYPE
435 #endif
436 // VTK-HeaderTest-Exclude: vtkDataArrayTemplate.h
437