vtkAOSDataArrayTemplate.h 12.6 KB
Newer Older
1 2 3
/*=========================================================================

  Program:   Visualization Toolkit
4
  Module:    vtkAOSDataArrayTemplate.h
5 6 7 8 9 10 11 12 13 14

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15 16 17
// .NAME vtkAOSDataArrayTemplate - Array-Of-Structs implementation of
// vtkGenericDataArray.
//
18
// .SECTION Description
19 20 21 22
// vtkGenericDataArray specialization that stores data array in the traditional
// VTK memory layout where a 3 component is stored in contiguous memory as
// \c A1A2A2B1B2B3C1C2C3 ... where A,B,C,... are tuples.
//
23
// This replaces vtkDataArrayTemplate.
24 25 26
//
// .SECTION See Also
// vtkGenericDataArray vtkSOADataArrayTemplate
27

28 29
#ifndef vtkAOSDataArrayTemplate_h
#define vtkAOSDataArrayTemplate_h
30

31
#include "vtkCommonCoreModule.h" // For export macro
32
#include "vtkGenericDataArray.h"
33
#include "vtkBuffer.h" // For storage buffer.
34

35 36
// The export macro below makes no sense, but is necessary for older compilers
// when we export instantiations of this class from vtkCommonCore.
37
template <class ValueTypeT>
38 39
class VTKCOMMONCORE_EXPORT vtkAOSDataArrayTemplate :
    public vtkGenericDataArray<vtkAOSDataArrayTemplate<ValueTypeT>, ValueTypeT>
40
{
41
  typedef vtkGenericDataArray<vtkAOSDataArrayTemplate<ValueTypeT>, ValueTypeT>
42
          GenericDataArrayType;
43
public:
44
  typedef vtkAOSDataArrayTemplate<ValueTypeT> SelfType;
45
  vtkTemplateTypeMacro(SelfType, GenericDataArrayType)
46
  typedef typename Superclass::ValueType ValueType;
47

48 49 50 51 52
  enum DeleteMethod
    {
    VTK_DATA_ARRAY_FREE=vtkBuffer<ValueType>::VTK_DATA_ARRAY_FREE,
    VTK_DATA_ARRAY_DELETE=vtkBuffer<ValueType>::VTK_DATA_ARRAY_DELETE
    };
53

54
  static vtkAOSDataArrayTemplate* New();
55

56 57
  // Description:
  // Get the value at @a valueIdx. @a valueIdx assumes AOS ordering.
David C. Lonie's avatar
David C. Lonie committed
58
  inline ValueType GetValue(vtkIdType valueIdx) const
59
  {
60
    return this->Buffer->GetBuffer()[valueIdx];
61 62 63 64 65 66 67 68 69 70 71
  }

  // Description:
  // Set the value at @a valueIdx to @a value. @a valueIdx assumes AOS ordering.
  inline void SetValue(vtkIdType valueIdx, ValueType value)
  {
    this->Buffer->GetBuffer()[valueIdx] = value;
  }

  // Description:
  // Copy the tuple at @a tupleIdx into @a tuple.
David C. Lonie's avatar
David C. Lonie committed
72
  inline void GetTypedTuple(vtkIdType tupleIdx, ValueType* tuple) const
73
  {
74
    const vtkIdType valueIdx = tupleIdx * this->NumberOfComponents;
75 76
    std::copy(this->Buffer->GetBuffer() + valueIdx,
              this->Buffer->GetBuffer() + valueIdx + this->NumberOfComponents,
77
              tuple);
78 79 80 81
  }

  // Description:
  // Set this array's tuple at @a tupleIdx to the values in @a tuple.
David C. Lonie's avatar
David C. Lonie committed
82
  inline void SetTypedTuple(vtkIdType tupleIdx, const ValueType* tuple)
83
  {
84 85
    const vtkIdType valueIdx = tupleIdx * this->NumberOfComponents;
    std::copy(tuple, tuple + this->NumberOfComponents,
86
              this->Buffer->GetBuffer() + valueIdx);
87 88 89 90 91 92 93 94 95 96 97
  }

  // Description:
  // Get component @a comp of the tuple at @a tupleIdx.
  inline ValueType GetTypedComponent(vtkIdType tupleIdx, int comp) const
  {
    return this->Buffer->GetBuffer()[this->NumberOfComponents*tupleIdx + comp];
  }

  // Description:
  // Set component @a comp of the tuple at @a tupleIdx to @a value.
David C. Lonie's avatar
David C. Lonie committed
98
  inline void SetTypedComponent(vtkIdType tupleIdx, int comp, ValueType value)
99
  {
100 101
    const vtkIdType valueIdx = tupleIdx * this->NumberOfComponents + comp;
    this->SetValue(valueIdx, value);
102
  }
103

104 105 106 107
  // Description:
  // Get the address of a particular data index. Make sure data is allocated
  // for the number of items requested. Set MaxId according to the number of
  // data values requested.
108
  ValueType* WritePointer(vtkIdType valueIdx, vtkIdType numValues);
109
  void* WriteVoidPointer(vtkIdType valueIdx, vtkIdType numValues) VTK_OVERRIDE;
110 111 112 113

  // Description:
  // Get the address of a particular data index. Performs no checks
  // to verify that the memory has been allocated etc.
114 115 116 117
  // Use of this method is discouraged, as newer arrays require a deep-copy of
  // the array data in order to return a suitable pointer. See vtkArrayDispatch
  // for a safer alternative for fast data access.
  ValueType* GetPointer(vtkIdType valueIdx);
118
  void* GetVoidPointer(vtkIdType valueIdx) VTK_OVERRIDE;
119 120 121 122 123 124 125 126 127 128 129

  // Description:
  // This method lets the user specify data to be held by the array.  The
  // array argument is a pointer to the data.  size is the size of the
  // array supplied by the user.  Set save to 1 to keep the class from
  // deleting the array when it cleans up or reallocates memory.  The class
  // uses the actual array provided; it does not copy the data from the
  // suppled array. If specified, the delete method determines how the data
  // array will be deallocated. If the delete method is
  // VTK_DATA_ARRAY_FREE, free() will be used. If the delete method is
  // DELETE, delete[] will be used. The default is FREE.
130
  void SetArray(ValueType* array, vtkIdType size, int save, int deleteMethod);
131
  void SetArray(ValueType* array, vtkIdType size, int save);
132 133 134
  void SetVoidArray(void* array, vtkIdType size, int save) VTK_OVERRIDE;
  void SetVoidArray(void* array, vtkIdType size, int save,
                    int deleteMethod) VTK_OVERRIDE;
135

136 137 138 139 140 141 142
  // Description:
  // Tell the array explicitly that a single data element has
  // changed. Like DataChanged(), then is only necessary when you
  // modify the array contents without using the array's API.
  // @note This is a legacy method from vtkDataArrayTemplate, and is only
  // implemented for array-of-struct arrays. It currently just calls
  // DataChanged() and does nothing clever.
143 144 145
  // TODO this is only defined for AOS (vtkDataArrayTemplate leftover).
  // Deprecate to favor DataChanged?
  void DataElementChanged(vtkIdType) { this->DataChanged(); }
146

147 148 149 150 151 152
  // Description:
  // Legacy support for array-of-structs value iteration.
  // TODO Deprecate?
  typedef ValueType* Iterator;
  Iterator Begin() { return Iterator(this->GetVoidPointer(0)); }
  Iterator End() { return Iterator(this->GetVoidPointer(this->MaxId + 1)); }
153

154 155
  // Description:
  // Perform a fast, safe cast from a vtkAbstractArray to a
156
  // vtkAOSDataArrayTemplate.
157 158 159
  // This method checks if source->GetArrayType() returns DataArray
  // or a more derived type, and performs a static_cast to return
  // source as a vtkDataArray pointer. Otherwise, NULL is returned.
160
  static vtkAOSDataArrayTemplate<ValueType>*
David C. Lonie's avatar
David C. Lonie committed
161
  FastDownCast(vtkAbstractArray *source)
162
  {
163
    if (source)
164
      {
165 166 167 168 169 170 171 172 173 174
      switch (source->GetArrayType())
        {
        case vtkAbstractArray::AoSDataArrayTemplate:
          if (vtkDataTypesCompare(source->GetDataType(),
                                  vtkTypeTraits<ValueType>::VTK_TYPE_ID))
            {
            return static_cast<vtkAOSDataArrayTemplate<ValueType>*>(source);
            }
          break;
        }
175 176 177 178
      }
    return NULL;
  }

179 180 181 182
  int GetArrayType() VTK_OVERRIDE { return vtkAbstractArray::AoSDataArrayTemplate; }
  VTK_NEWINSTANCE vtkArrayIterator *NewIterator() VTK_OVERRIDE;
  bool HasStandardMemoryLayout() VTK_OVERRIDE { return true; }
  void ShallowCopy(vtkDataArray *other) VTK_OVERRIDE;
183

184 185 186 187 188 189 190 191
  // Description:
  // @deprecated Replace TupleValue with TypedTuple to use the new method
  // names. Note that the new signatures are also const-correct.
  VTK_LEGACY(void GetTupleValue(vtkIdType tupleIdx, ValueType *tuple));
  VTK_LEGACY(void SetTupleValue(vtkIdType tupleIdx, const ValueType *tuple));
  VTK_LEGACY(void InsertTupleValue(vtkIdType tupleIdx, const ValueType *tuple));
  VTK_LEGACY(vtkIdType InsertNextTupleValue(const ValueType *tuple));

192
  // Reimplemented for efficiency:
193 194
  void InsertTuples(vtkIdType dstStart, vtkIdType n, vtkIdType srcStart,
                    vtkAbstractArray* source) VTK_OVERRIDE;
195
  // MSVC doesn't like 'using' here (error C2487). Just forward instead:
196 197 198
  // using Superclass::InsertTuples;
  void InsertTuples(vtkIdList *dstIds, vtkIdList *srcIds,
                    vtkAbstractArray *source) VTK_OVERRIDE
199 200
  { this->Superclass::InsertTuples(dstIds, srcIds, source); }

201
protected:
202 203
  vtkAOSDataArrayTemplate();
  ~vtkAOSDataArrayTemplate();
204

205 206 207
  // Description:
  // Allocate space for numTuples. Old data is not preserved. If numTuples == 0,
  // all data is freed.
208
  bool AllocateTuples(vtkIdType numTuples);
209 210 211 212

  // Description:
  // Allocate space for numTuples. Old data is preserved. If numTuples == 0,
  // all data is freed.
213 214
  bool ReallocateTuples(vtkIdType numTuples);

215
  vtkBuffer<ValueType> *Buffer;
216 217

private:
218
  vtkAOSDataArrayTemplate(const vtkAOSDataArrayTemplate&) VTK_DELETE_FUNCTION;
219
  void operator=(const vtkAOSDataArrayTemplate&) VTK_DELETE_FUNCTION;
220

221
  friend class vtkGenericDataArray<vtkAOSDataArrayTemplate<ValueTypeT>,
222
                                   ValueTypeT>;
223

224 225
};

David C. Lonie's avatar
David C. Lonie committed
226
// Declare vtkArrayDownCast implementations for AoS containers:
227
vtkArrayDownCast_TemplateFastCastMacro(vtkAOSDataArrayTemplate)
David C. Lonie's avatar
David C. Lonie committed
228

229 230
// This macro is used by the subclasses to create dummy
// declarations for these functions such that the wrapper
231
// can see them. The wrappers ignore vtkAOSDataArrayTemplate.
232 233
#define vtkCreateWrappedArrayInterface(T) \
  int GetDataType(); \
David C. Lonie's avatar
David C. Lonie committed
234 235 236 237
  void GetTypedTuple(vtkIdType i, T* tuple); \
  void SetTypedTuple(vtkIdType i, const T* tuple); \
  void InsertTypedTuple(vtkIdType i, const T* tuple); \
  vtkIdType InsertNextTypedTuple(const T* tuple); \
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
  T GetValue(vtkIdType id); \
  void SetValue(vtkIdType id, T value); \
  void SetNumberOfValues(vtkIdType number); \
  void InsertValue(vtkIdType id, T f); \
  vtkIdType InsertNextValue(T f); \
  T *GetValueRange(int comp); \
  T *GetValueRange(); \
  T* WritePointer(vtkIdType id, vtkIdType number); \
  T* GetPointer(vtkIdType id)/*; \

  * These methods are not wrapped to avoid wrappers exposing these
  * easy-to-get-wrong methods because passing in the wrong value for 'save' is
  * guaranteed to cause a memory issue down the line. Either the wrappers
  * didn't use malloc to allocate the memory or the memory isn't actually
  * persisted because a temporary array is used that doesn't persist like this
  * method expects.

  void SetArray(T* array, vtkIdType size, int save); \
  void SetArray(T* array, vtkIdType size, int save, int deleteMethod) */
257 258 259 260 261

#endif // header guard

// This portion must be OUTSIDE the include blockers. This is used to tell
// libraries other than vtkCommonCore that instantiations of
262
// vtkAOSDataArrayTemplate can be found externally. This prevents each library
263
// from instantiating these on their own.
264 265 266 267 268 269 270 271 272 273 274 275 276
#ifdef VTK_AOS_DATA_ARRAY_TEMPLATE_INSTANTIATING
#define VTK_AOS_DATA_ARRAY_TEMPLATE_INSTANTIATE(T) \
  template class VTKCOMMONCORE_EXPORT vtkAOSDataArrayTemplate< T >
#elif defined(VTK_USE_EXTERN_TEMPLATE)
#ifndef VTK_AOS_DATA_ARRAY_TEMPLATE_EXTERN
#define VTK_AOS_DATA_ARRAY_TEMPLATE_EXTERN
#ifdef _MSC_VER
#pragma warning (push)
// The following is needed when the vtkAOSDataArrayTemplate is declared
// dllexport and is used from another class in vtkCommonCore
#pragma warning (disable: 4910) // extern and dllexport incompatible
#endif
vtkExternTemplateMacro(
277
  extern template class VTKCOMMONCORE_EXPORT vtkAOSDataArrayTemplate)
278 279 280 281 282 283 284
#ifdef _MSC_VER
#pragma warning (pop)
#endif
#endif // VTK_AOS_DATA_ARRAY_TEMPLATE_EXTERN

// The following clause is only for MSVC 2008 and 2010
#elif defined(_MSC_VER) && !defined(VTK_BUILD_SHARED_LIBS)
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
#pragma warning (push)

// C4091: 'extern ' : ignored on left of 'int' when no variable is declared
#pragma warning (disable: 4091)

// Compiler-specific extension warning.
#pragma warning (disable: 4231)

// We need to disable warning 4910 and do an extern dllexport
// anyway.  When deriving vtkCharArray and other types from an
// instantiation of this template the compiler does an explicit
// instantiation of the base class.  From outside the vtkCommon
// library we block this using an extern dllimport instantiation.
// For classes inside vtkCommon we should be able to just do an
// extern instantiation, but VS 2008 complains about missing
// definitions.  We cannot do an extern dllimport inside vtkCommon
// since the symbols are local to the dll.  An extern dllexport
// seems to be the only way to convince VS 2008 to do the right
// thing, so we just disable the warning.
#pragma warning (disable: 4910) // extern and dllexport incompatible

// Use an "extern explicit instantiation" to give the class a DLL
// interface.  This is a compiler-specific extension.
308 309
vtkInstantiateTemplateMacro(
  extern template class VTKCOMMONCORE_EXPORT vtkAOSDataArrayTemplate)
310 311

#pragma warning (pop)
312 313

#endif
314

315
// VTK-HeaderTest-Exclude: vtkAOSDataArrayTemplate.h