VTK  9.7.1
DataArrayConverters.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-FileCopyrightText: Copyright (c) Kitware, Inc.
3 // SPDX-FileCopyrightText: Copyright 2012 Sandia Corporation.
4 // SPDX-License-Identifier: LicenseRef-BSD-3-Clause-Sandia-USGov
5 
6 #ifndef vtkmlib_DataArrayConverters_h
7 #define vtkmlib_DataArrayConverters_h
8 
9 #include "vtkAcceleratorsVTKmCoreModule.h" //required for correct implementation
10 #include "vtkmConfigCore.h" //required for general viskores setup
11 
13 #include "vtkAffineArray.h"
14 #include "vtkConstantArray.h"
16 
17 #include "vtkLogger.h"
18 
19 #include <viskores/cont/ArrayExtractComponent.h>
20 #include <viskores/cont/ArrayHandleBasic.h>
21 #include <viskores/cont/ArrayHandleConstant.h>
22 #include <viskores/cont/ArrayHandleCounting.h>
23 #include <viskores/cont/ArrayHandleIndex.h>
24 #include <viskores/cont/ArrayHandleRecombineVec.h>
25 #include <viskores/cont/ArrayHandleRuntimeVec.h>
26 #include <viskores/cont/ArrayHandleSOA.h>
27 #include <viskores/cont/ArrayHandleStride.h>
28 #include <viskores/cont/Field.h>
29 #include <viskores/cont/UnknownArrayHandle.h>
30 
31 #include <type_traits> // for std::underlying_type
32 #include <utility> // for std::pair
33 
34 namespace viskores
35 {
36 namespace cont
37 {
38 class CoordinateSystem;
39 }
40 }
41 
42 VTK_ABI_NAMESPACE_BEGIN
43 class vtkDataArray;
44 class vtkPoints;
45 VTK_ABI_NAMESPACE_END
46 
47 namespace tovtkm
48 {
49 VTK_ABI_NAMESPACE_BEGIN
50 
54 inline static const char* NoNameVTKFieldName()
55 {
56  static const char* name = "NoNameVTKField";
57  return name;
58 }
59 
60 template <typename T>
61 viskores::cont::ArrayHandleBasic<T> vtkAOSDataArrayToFlatArrayHandle(
63 {
64  // Register a reference to the input here to make sure the array cannot
65  // be deleted before the `ArrayHandle` is done with it. (Note that you
66  // will still get problems if the `vtkAOSDataArrayTemplate` gets resized.
67  input->Register(nullptr);
68 
69  auto deleter = [](void* container)
70  {
71  vtkAOSDataArrayTemplate<T>* vtkArray = reinterpret_cast<vtkAOSDataArrayTemplate<T>*>(container);
72  vtkArray->UnRegister(nullptr);
73  };
74  auto reallocator = [](void*& memory, void*& container, viskores::BufferSizeType oldSize,
75  viskores::BufferSizeType newSize)
76  {
77  vtkAOSDataArrayTemplate<T>* vtkArray = reinterpret_cast<vtkAOSDataArrayTemplate<T>*>(container);
78  if ((vtkArray->GetPointer(0) != memory) || (vtkArray->GetNumberOfValues() != oldSize))
79  {
80  vtkLog(ERROR,
81  "Dangerous inconsistency found between pointers for VTK and Viskores. "
82  "Was the VTK array resized outside of Viskores?");
83  }
84  vtkArray->SetNumberOfValues(newSize);
85  memory = vtkArray->GetPointer(0);
86  };
87 
88  return viskores::cont::ArrayHandleBasic<T>(
89  input->GetPointer(0), input, input->GetNumberOfValues(), deleter, reallocator);
90 }
91 
92 template <typename T>
93 viskores::cont::ArrayHandleBasic<T> vtkSOADataArrayToComponentArrayHandle(
94  vtkSOADataArrayTemplate<T>* input, int componentIndex)
95 {
96  // Register for each component (as each will have the deleter call to
97  // unregister).
98  input->Register(nullptr);
99 
100  using ContainerPair = std::pair<vtkSOADataArrayTemplate<T>*, int>;
101  ContainerPair* componentInput = new ContainerPair(input, componentIndex);
102 
103  auto deleter = [](void* container)
104  {
105  ContainerPair* containerPair = reinterpret_cast<ContainerPair*>(container);
106  containerPair->first->UnRegister(nullptr);
107  delete containerPair;
108  };
109  auto reallocator = [](void*& memory, void*& container,
110  viskores::BufferSizeType vtkNotUsed(oldSize),
111  viskores::BufferSizeType newSize)
112  {
113  ContainerPair* containerPair = reinterpret_cast<ContainerPair*>(container);
114  containerPair->first->SetNumberOfTuples(newSize);
115  memory = containerPair->first->GetComponentArrayPointer(containerPair->second);
116  };
117 
118  return viskores::cont::ArrayHandleBasic<T>(input->GetComponentArrayPointer(componentIndex),
119  componentInput, input->GetNumberOfTuples(), deleter, reallocator);
120 }
121 
122 template <typename T>
123 viskores::cont::ArrayHandleRuntimeVec<T> vtkDataArrayToArrayHandle(
125 {
126  auto flatArray = vtkAOSDataArrayToFlatArrayHandle(input);
127  return viskores::cont::make_ArrayHandleRuntimeVec(input->GetNumberOfComponents(), flatArray);
128 }
129 
130 template <typename T>
131 viskores::cont::ArrayHandleRecombineVec<T> vtkDataArrayToArrayHandle(
133 {
134  // Wrap each component array in a basic array handle, convert that to a
135  // strided array, and then add that as a component to the returned
136  // recombined vec.
137  viskores::cont::ArrayHandleRecombineVec<T> output;
138 
139  for (int componentIndex = 0; componentIndex < input->GetNumberOfComponents(); ++componentIndex)
140  {
141  auto componentArray = vtkSOADataArrayToComponentArrayHandle(input, componentIndex);
142  output.AppendComponentArray(
143  viskores::cont::ArrayExtractComponent(componentArray, 0, viskores::CopyFlag::Off));
144  }
145 
146  return output;
147 }
148 
149 template <typename VecT>
150 viskores::cont::ArrayHandleConstant<VecT> vtkDataArrayToArrayHandle(
151  vtkConstantArray<typename viskores::VecTraits<VecT>::ComponentType>* input)
152 {
153  return viskores::cont::ArrayHandleConstant<VecT>(
154  VecT{ input->GetBackend()->Value }, input->GetNumberOfTuples());
155 }
156 
157 template <typename T>
158 viskores::cont::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(vtkConstantArray<T>* input)
159 {
160  switch (input->GetNumberOfComponents())
161  {
162  case 1:
163  return vtkDataArrayToArrayHandle<T>(input);
164  case 2:
165  return vtkDataArrayToArrayHandle<viskores::Vec<T, 2>>(input);
166  case 3:
167  return vtkDataArrayToArrayHandle<viskores::Vec<T, 3>>(input);
168  case 4:
169  return vtkDataArrayToArrayHandle<viskores::Vec<T, 4>>(input);
170  default:
171  vtkGenericWarningMacro(<< "Cannot convert constant array with "
172  << input->GetNumberOfComponents() << " components.");
173  return viskores::cont::UnknownArrayHandle{};
174  }
175 }
176 
177 template <typename T>
178 viskores::cont::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(vtkAffineArray<T>* input)
179 {
180  if (input->GetNumberOfComponents() != 1)
181  {
182  vtkGenericWarningMacro(<< "Cannot convert affine array with " << input->GetNumberOfComponents()
183  << " components.");
184  return viskores::cont::UnknownArrayHandle{};
185  }
186 
187  T start = input->GetBackend()->Intercept;
188  T step = input->GetBackend()->Slope;
189  viskores::Id length = input->GetNumberOfValues();
190  if ((start == 0) && (step == 1))
191  {
192  // Represent as an index array, which is less versatile but faster and has
193  // better supported conversions. This could cause a type conversion, but all
194  // values are exactly integers.
195  return viskores::cont::ArrayHandleIndex(length);
196  }
197  else
198  {
199  return viskores::cont::ArrayHandleCounting<T>(start, step, length);
200  }
201 }
202 
203 template <typename DataArrayType>
204 viskores::cont::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(DataArrayType* input)
205 {
206  return vtkDataArrayToArrayHandle(input);
207 }
208 
209 enum class FieldsFlag
210 {
211  None = 0x0,
212  Points = 0x1,
213  Cells = 0x2,
214 
216 };
217 
218 VTK_ABI_NAMESPACE_END
219 }
220 
221 namespace fromvtkm
222 {
223 VTK_ABI_NAMESPACE_BEGIN
224 
225 VTKACCELERATORSVTKMCORE_EXPORT
226 vtkDataArray* Convert(const viskores::cont::Field& input);
227 
228 VTKACCELERATORSVTKMCORE_EXPORT
229 vtkDataArray* Convert(const viskores::cont::UnknownArrayHandle& input, const std::string& name);
230 
231 VTKACCELERATORSVTKMCORE_EXPORT
232 vtkPoints* Convert(const viskores::cont::CoordinateSystem& input);
233 
234 VTK_ABI_NAMESPACE_END
235 }
236 
237 VTK_ABI_NAMESPACE_BEGIN
239 {
241  return static_cast<tovtkm::FieldsFlag>(static_cast<T>(a) & static_cast<T>(b));
242 }
243 
245 {
247  return static_cast<tovtkm::FieldsFlag>(static_cast<T>(a) | static_cast<T>(b));
248 }
249 VTK_ABI_NAMESPACE_END
250 
251 #endif // vtkmlib_ArrayConverters_h
252 /* VTK-HeaderTest-Exclude: DataArrayConverters.h */
Struct-Of-Arrays implementation of vtkGenericDataArray.
tovtkm::FieldsFlag operator&(const tovtkm::FieldsFlag &a, const tovtkm::FieldsFlag &b)
int GetNumberOfComponents() const
Set/Get the dimension (n) of the components.
ValueType * GetPointer(vtkIdType valueIdx)
Get the address of a particular data index.
A utility array for wrapping constant functions in implicit arrays.
Abstract interface for N-dimensional arrays.
Definition: vtkArray.h:51
tovtkm::FieldsFlag operator|(const tovtkm::FieldsFlag &a, const tovtkm::FieldsFlag &b)
ValueType * GetComponentArrayPointer(int comp)
Return a pointer to a contiguous block of memory containing all values for a particular components (i...
vtkIdType GetNumberOfValues() const
Get the total number of values in the array.
static const char * NoNameVTKFieldName()
Temporary name for arrays converted from VTK that do not have a name.
viskores::cont::ArrayHandleBasic< T > vtkSOADataArrayToComponentArrayHandle(vtkSOADataArrayTemplate< T > *input, int componentIndex)
viskores::cont::ArrayHandleBasic< T > vtkAOSDataArrayToFlatArrayHandle(vtkAOSDataArrayTemplate< T > *input)
virtual void UnRegister(vtkObjectBase *o)
Decrease the reference count (release by another object).
Array-Of-Structs implementation of vtkGenericDataArray.
#define vtkLog(verbosity_name, x)
Add to log given the verbosity level.
Definition: vtkLogger.h:494
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:44
void Register(vtkObjectBase *o)
Increase the reference count (mark as used by another object).
vtkIdType GetNumberOfTuples() const
Get the number of complete tuples (a component group) in the array.
A utility array for wrapping affine functions in implicit arrays.
VTKACCELERATORSVTKMCORE_EXPORT vtkDataArray * Convert(const viskores::cont::Field &input)
viskores::cont::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(vtkConstantArray< T > *input)
virtual bool SetNumberOfValues(vtkIdType numValues)
Specify the number of values (tuples * components) for this object to hold.
represent and manipulate 3D points
Definition: vtkPoints.h:30
viskores::cont::ArrayHandleRuntimeVec< T > vtkDataArrayToArrayHandle(vtkAOSDataArrayTemplate< T > *input)