1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkMergeArrays.cxx
5
6 Copyright (c) Kitware, Inc.
7 All rights reserved.
8 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkMergeArrays.h"
16
17 #include "vtkCellData.h"
18 #include "vtkCompositeDataIterator.h"
19 #include "vtkCompositeDataSet.h"
20 #include "vtkDataArray.h"
21 #include "vtkDataSet.h"
22 #include "vtkFieldData.h"
23 #include "vtkInformation.h"
24 #include "vtkInformationVector.h"
25 #include "vtkObjectFactory.h"
26 #include "vtkPointData.h"
27 #include "vtkSmartPointer.h"
28
29 vtkStandardNewMacro(vtkMergeArrays);
30
31 //------------------------------------------------------------------------------
32 vtkMergeArrays::vtkMergeArrays() = default;
33
34 //------------------------------------------------------------------------------
35 vtkMergeArrays::~vtkMergeArrays() = default;
36
37 //------------------------------------------------------------------------------
GetOutputArrayName(vtkFieldData * arrays,const char * arrayName,int inputIndex,std::string & outputArrayName)38 bool vtkMergeArrays::GetOutputArrayName(
39 vtkFieldData* arrays, const char* arrayName, int inputIndex, std::string& outputArrayName)
40 {
41 if (arrays->GetAbstractArray(arrayName) == nullptr)
42 {
43 return false;
44 }
45 outputArrayName = std::string(arrayName) + "_input_" + std::to_string(inputIndex);
46 return true;
47 }
48
49 //------------------------------------------------------------------------------
MergeArrays(int inputIndex,vtkFieldData * inputFD,vtkFieldData * outputFD)50 void vtkMergeArrays::MergeArrays(int inputIndex, vtkFieldData* inputFD, vtkFieldData* outputFD)
51 {
52 if (inputFD == nullptr || outputFD == nullptr)
53 {
54 return;
55 }
56
57 std::string outputArrayName;
58 int numArrays = inputFD->GetNumberOfArrays();
59 for (int arrayIdx = 0; arrayIdx < numArrays; ++arrayIdx)
60 {
61 vtkAbstractArray* array = inputFD->GetAbstractArray(arrayIdx);
62 if (this->GetOutputArrayName(outputFD, array->GetName(), inputIndex, outputArrayName))
63 {
64 vtkAbstractArray* newArray = array->NewInstance();
65 if (vtkDataArray* newDataArray = vtkDataArray::SafeDownCast(newArray))
66 {
67 newDataArray->ShallowCopy(vtkDataArray::SafeDownCast(array));
68 }
69 else
70 {
71 newArray->DeepCopy(array);
72 }
73 newArray->SetName(outputArrayName.c_str());
74 outputFD->AddArray(newArray);
75 newArray->FastDelete();
76 }
77 else
78 {
79 outputFD->AddArray(array);
80 }
81 }
82 }
83
84 //------------------------------------------------------------------------------
MergeDataObjectFields(vtkDataObject * input,int idx,vtkDataObject * output)85 int vtkMergeArrays::MergeDataObjectFields(vtkDataObject* input, int idx, vtkDataObject* output)
86 {
87 if (!input || !output)
88 {
89 return 0;
90 }
91
92 int checks[vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES];
93 for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
94 {
95 checks[attr] = output->GetNumberOfElements(attr) == input->GetNumberOfElements(attr) ? 0 : 1;
96 }
97 int globalChecks[vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES];
98
99 for (int i = 0; i < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; ++i)
100 {
101 globalChecks[i] = checks[i];
102 }
103
104 for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
105 {
106 if (globalChecks[attr] == 0)
107 {
108 // only merge arrays when the number of elements in the input and output are the same
109 this->MergeArrays(
110 idx, input->GetAttributesAsFieldData(attr), output->GetAttributesAsFieldData(attr));
111 }
112 }
113
114 return 1;
115 }
116
117 //------------------------------------------------------------------------------
FillInputPortInformation(int vtkNotUsed (port),vtkInformation * info)118 int vtkMergeArrays::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info)
119 {
120 info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
121 return 1;
122 }
123
124 //------------------------------------------------------------------------------
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)125 int vtkMergeArrays::RequestData(vtkInformation* vtkNotUsed(request),
126 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
127 {
128 int num = inputVector[0]->GetNumberOfInformationObjects();
129 if (num < 1)
130 {
131 return 0;
132 }
133 // get the output info object
134 vtkInformation* outInfo = outputVector->GetInformationObject(0);
135 vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
136
137 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
138 vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
139
140 vtkCompositeDataSet* cOutput = vtkCompositeDataSet::SafeDownCast(output);
141 if (cOutput)
142 {
143 vtkCompositeDataSet* cInput = vtkCompositeDataSet::SafeDownCast(input);
144 cOutput->CopyStructure(cInput);
145 vtkSmartPointer<vtkCompositeDataIterator> iter;
146 iter.TakeReference(cInput->NewIterator());
147 iter->InitTraversal();
148 for (; !iter->IsDoneWithTraversal(); iter->GoToNextItem())
149 {
150 if (vtkDataSet* tmpIn = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject()))
151 {
152 vtkDataSet* tmpOut = tmpIn->NewInstance();
153 tmpOut->ShallowCopy(tmpIn);
154 cOutput->SetDataSet(iter, tmpOut);
155 tmpOut->Delete();
156 }
157 }
158 }
159 else
160 {
161 output->ShallowCopy(input);
162 }
163
164 for (int idx = 1; idx < num; ++idx)
165 {
166 inInfo = inputVector[0]->GetInformationObject(idx);
167 input = inInfo->Get(vtkDataObject::DATA_OBJECT());
168 if (!this->MergeDataObjectFields(input, idx, output))
169 {
170 return 0;
171 }
172 vtkCompositeDataSet* cInput = vtkCompositeDataSet::SafeDownCast(input);
173 if (cOutput && cInput)
174 {
175 vtkSmartPointer<vtkCompositeDataIterator> iter;
176 iter.TakeReference(cInput->NewIterator());
177 iter->InitTraversal();
178 for (; !iter->IsDoneWithTraversal(); iter->GoToNextItem())
179 {
180 vtkDataObject* tmpIn = iter->GetCurrentDataObject();
181 vtkDataObject* tmpOut = cOutput->GetDataSet(iter);
182 if (!this->MergeDataObjectFields(tmpIn, idx, tmpOut))
183 {
184 return 0;
185 }
186 }
187 }
188 }
189 return 1;
190 }
191
192 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)193 void vtkMergeArrays::PrintSelf(ostream& os, vtkIndent indent)
194 {
195 this->Superclass::PrintSelf(os, indent);
196 }
197