------------------------------------------------------------------------------
| 173 | |
| 174 | //------------------------------------------------------------------------------ |
| 175 | vtkSmartPointer<vtkDataArray> ApplyMorphingToDataArray(vtkSmartPointer<vtkDataArray> origin, |
| 176 | const std::vector<float>& weights, const std::vector<vtkSmartPointer<vtkFloatArray>>& targets) |
| 177 | { |
| 178 | if (origin == nullptr) |
| 179 | { |
| 180 | return nullptr; |
| 181 | } |
| 182 | |
| 183 | vtkSmartPointer<vtkDataArray> result = vtkSmartPointer<vtkDataArray>::Take(origin->NewInstance()); |
| 184 | result->DeepCopy(origin); |
| 185 | |
| 186 | if (targets.empty() || weights.empty() || targets.size() != weights.size()) |
| 187 | { |
| 188 | return origin; |
| 189 | } |
| 190 | std::vector<double> tuple(origin->GetNumberOfComponents(), 0); |
| 191 | for (int tupleId = 0; tupleId < origin->GetNumberOfTuples(); tupleId++) |
| 192 | { |
| 193 | origin->GetTuple(tupleId, tuple.data()); |
| 194 | for (unsigned int targetId = 0; targetId < targets.size(); targetId++) |
| 195 | { |
| 196 | for (int component = 0; component < targets[targetId]->GetNumberOfComponents(); component++) |
| 197 | { |
| 198 | // Morphing: |
| 199 | // P the resulting tuple, P0 the primitive's tuple, wi the weights, Ti the targets' tuples: |
| 200 | // P = P0 + sum(wi * Ti) |
| 201 | tuple[component] += weights[targetId] * targets[targetId]->GetTuple(tupleId)[component]; |
| 202 | } |
| 203 | } |
| 204 | result->SetTuple(tupleId, tuple.data()); |
| 205 | } |
| 206 | return result; |
| 207 | } |
| 208 | |
| 209 | //------------------------------------------------------------------------------ |
| 210 | void SetupWeightedTransformFilterForGLTFSkinning(vtkSmartPointer<vtkWeightedTransformFilter> filter, |
no test coverage detected