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