VTK  9.6.20260307
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
34namespace viskores
35{
36namespace cont
37{
38class CoordinateSystem;
39}
40}
41
42VTK_ABI_NAMESPACE_BEGIN
43class vtkDataArray;
44class vtkPoints;
45VTK_ABI_NAMESPACE_END
46
47namespace tovtkm
48{
49VTK_ABI_NAMESPACE_BEGIN
50
54inline static const char* NoNameVTKFieldName()
55{
56 static const char* name = "NoNameVTKField";
57 return name;
58}
59
60template <typename T>
61viskores::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
92template <typename T>
93viskores::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
122template <typename T>
123viskores::cont::ArrayHandleRuntimeVec<T> vtkDataArrayToArrayHandle(
125{
126 auto flatArray = vtkAOSDataArrayToFlatArrayHandle(input);
127 return viskores::cont::make_ArrayHandleRuntimeVec(input->GetNumberOfComponents(), flatArray);
128}
129
130template <typename T>
131viskores::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
149template <typename VecT>
150viskores::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
157template <typename T>
158viskores::cont::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(vtkConstantArray<T>* input)
159{
160 switch (input->GetNumberOfComponents())
161 {
162 case 1:
163 return vtkDataArrayToArrayHandle<T>(input);
164 case 2:
166 case 3:
168 case 4:
170 default:
171 vtkGenericWarningMacro(<< "Cannot convert constant array with "
172 << input->GetNumberOfComponents() << " components.");
173 return viskores::cont::UnknownArrayHandle{};
174 }
175}
176
177template <typename T>
178viskores::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
203template <typename DataArrayType>
204viskores::cont::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(DataArrayType* input)
205{
206 return vtkDataArrayToArrayHandle(input);
207}
208
209enum class FieldsFlag
210{
211 None = 0x0,
212 Points = 0x1,
213 Cells = 0x2,
214
216};
217
218VTK_ABI_NAMESPACE_END
219}
220
221namespace fromvtkm
222{
223VTK_ABI_NAMESPACE_BEGIN
224
225VTKACCELERATORSVTKMCORE_EXPORT
226vtkDataArray* Convert(const viskores::cont::Field& input);
227
228VTKACCELERATORSVTKMCORE_EXPORT
229vtkDataArray* Convert(const viskores::cont::UnknownArrayHandle& input, const std::string& name);
230
231VTKACCELERATORSVTKMCORE_EXPORT
232vtkPoints* Convert(const viskores::cont::CoordinateSystem& input);
233
234VTK_ABI_NAMESPACE_END
235}
236
237VTK_ABI_NAMESPACE_BEGIN
239{
240 using T = std::underlying_type<tovtkm::FieldsFlag>::type;
241 return static_cast<tovtkm::FieldsFlag>(static_cast<T>(a) & static_cast<T>(b));
242}
243
245{
246 using T = std::underlying_type<tovtkm::FieldsFlag>::type;
247 return static_cast<tovtkm::FieldsFlag>(static_cast<T>(a) | static_cast<T>(b));
248}
249VTK_ABI_NAMESPACE_END
250
251#endif // vtkmlib_ArrayConverters_h
252/* VTK-HeaderTest-Exclude: DataArrayConverters.h */
tovtkm::FieldsFlag operator&(const tovtkm::FieldsFlag &a, const tovtkm::FieldsFlag &b)
tovtkm::FieldsFlag operator|(const tovtkm::FieldsFlag &a, const tovtkm::FieldsFlag &b)
Array-Of-Structs implementation of vtkGenericDataArray.
ValueType * GetPointer(vtkIdType valueIdx)
Get the address of a particular data index.
int GetNumberOfComponents() const
Set/Get the dimension (n) of the components.
vtkIdType GetNumberOfTuples() const
Get the number of complete tuples (a component group) in the array.
vtkIdType GetNumberOfValues() const
Get the total number of values in the array.
A utility array for wrapping affine functions in implicit arrays.
Abstract interface for N-dimensional arrays.
Definition vtkArray.h:52
A utility array for wrapping constant functions in implicit arrays.
std::shared_ptr< BackendT > GetBackend()
Setter/Getter for Backend.
virtual void UnRegister(vtkObjectBase *o)
Decrease the reference count (release by another object).
void Register(vtkObjectBase *o)
Increase the reference count (mark as used by another object).
represent and manipulate 3D points
Definition vtkPoints.h:140
Struct-Of-Arrays implementation of vtkGenericDataArray.
ValueType * GetComponentArrayPointer(int comp)
Return a pointer to a contiguous block of memory containing all values for a particular components (i...
VTKACCELERATORSVTKMCORE_EXPORT vtkDataArray * Convert(const viskores::cont::Field &input)
viskores::cont::ArrayHandleBasic< T > vtkAOSDataArrayToFlatArrayHandle(vtkAOSDataArrayTemplate< T > *input)
viskores::cont::ArrayHandleRuntimeVec< T > vtkDataArrayToArrayHandle(vtkAOSDataArrayTemplate< T > *input)
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::UnknownArrayHandle vtkDataArrayToUnknownArrayHandle(vtkConstantArray< T > *input)
#define vtkDataArray
#define vtkLog(verbosity_name, x)
Add to log given the verbosity level.
Definition vtkLogger.h:513