41 std::cout << std::endl;
42 std::vector<int> identity(permutation.size());
43 std::iota(identity.begin(), identity.end(), 0);
44 return std::is_permutation(identity.begin(), identity.end(), permutation.begin());
66 float* data,
const std::vector<int64_t>& outputShape,
const std::vector<int>& permutation)
68 const size_t nDim = outputShape.size();
73 std::vector<int64_t> inputShape(outputShape.size());
75 for (
size_t i = 0; i < nDim; ++i)
77 inputShape[i] = outputShape[inversePermutation[i]];
81 auto computeStrides = [nDim](
const std::vector<int64_t>& shape)
83 std::vector<int64_t> strides(nDim);
84 strides[nDim - 1] = 1;
85 for (
int i =
static_cast<int>(nDim) - 2; i >= 0; --i)
87 strides[i] = strides[i + 1] * shape[i + 1];
92 std::vector<int64_t> inputStrides = computeStrides(inputShape);
93 std::vector<int64_t> outputStrides = computeStrides(outputShape);
96 std::vector<float> buffer(numElements);
98 [&](int64_t begin, int64_t end)
100 std::vector<int64_t> inputCoords(nDim);
101 std::vector<int64_t> outputCoords(nDim);
103 for (int64_t inputIndex = begin; inputIndex < end; ++inputIndex)
105 int tmpInputIndex = inputIndex;
107 for (
size_t i = 0; i < nDim; ++i)
109 inputCoords[i] = tmpInputIndex / inputStrides[i];
110 tmpInputIndex %= inputStrides[i];
114 for (
size_t i = 0; i < nDim; ++i)
116 outputCoords[i] = inputCoords[permutation[i]];
121 for (
size_t i = 0; i < nDim; ++i)
123 outputIndex += outputCoords[i] * outputStrides[i];
126 buffer[outputIndex] = data[inputIndex];
130 std::copy(buffer.begin(), buffer.end(), data);
138 int64_t numTuples, int64_t numComponents,
const std::vector<int64_t> modelShape)
140 if (modelShape.empty())
145 const int64_t vtkShape[2] = { numTuples, numComponents };
146 constexpr int vtkRank = 2;
147 const int modelRank =
static_cast<int>(modelShape.size());
150 const int64_t vtkTotalElements = numTuples * numComponents;
152 if (modelTotalElements != vtkTotalElements)
164 if (modelShape[0] == numTuples && modelShape[1] == numComponents)
169 if (modelShape[0] == numComponents && modelShape[1] == numTuples)
176 std::array<std::vector<int>, vtkRank> vtkToModelMapping;
178 std::vector<bool> usedModel(modelRank,
false);
179 std::vector<bool> usedVTK(vtkRank,
false);
181 for (
int i = 0; i < modelRank; ++i)
183 for (
int j = 0; j < vtkRank; ++j)
185 if (modelShape[i] == vtkShape[j] && !usedVTK[j] && !usedModel[i])
187 vtkToModelMapping[j].push_back(i);
195 auto forEachSelectedDimension = [&](
int productMask,
auto&& func)
199 for (
size_t i = 0; i < usedModel.size(); ++i)
203 if (productMask & (1 << bitShift))
213 for (
int j = 0; j < vtkRank; ++j)
219 const int64_t dimension = vtkShape[j];
220 int unusedShapeElements =
221 std::count_if(usedModel.begin(), usedModel.end(), [](
bool used) { return !used; });
223 for (
int productMask = (1 << unusedShapeElements); productMask > 0; --productMask)
225 int64_t extractedDimension = 1;
227 forEachSelectedDimension(productMask, [&](
size_t i) { extractedDimension *= modelShape[i]; });
229 if (extractedDimension == dimension)
233 forEachSelectedDimension(productMask,
236 vtkToModelMapping[j].push_back(i);
245 if (vtkToModelMapping[0].empty() || vtkToModelMapping[1].empty())
250 std::vector<int> permutation;
251 permutation.reserve(modelRank);
252 for (
int i = 0; i < vtkRank; ++i)
254 for (
int j = 0; j < static_cast<int>(vtkToModelMapping[i].size()); ++j)
256 permutation.push_back(vtkToModelMapping[i][j]);