TTK
Loading...
Searching...
No Matches
ttkArrayEditor.cpp
Go to the documentation of this file.
1#include <ttkArrayEditor.h>
2
3#include <vtkInformation.h>
4#include <vtkObjectFactory.h>
5
6#include <vtkAbstractArray.h>
7#include <vtkDataArray.h>
8#include <vtkDataSet.h>
9#include <vtkFieldData.h>
10#include <vtkSmartPointer.h>
11#include <vtkStringArray.h>
12
13#include <vtkCommand.h>
14#include <vtkDataArraySelection.h>
15
16#include <ttkUtils.h>
17
19
21 this->setDebugMsgPrefix("ArrayEditor");
22
23 this->SetNumberOfInputPorts(2);
24 this->SetNumberOfOutputPorts(1);
25
26 for(int cc = 0; cc < vtkDataObject::NUMBER_OF_ASSOCIATIONS; ++cc) {
27 if(cc != vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS) {
28 this->ArraySelections[cc] = vtkSmartPointer<vtkDataArraySelection>::New();
29 this->ArraySelections[cc]->AddObserver(
30 vtkCommand::ModifiedEvent, this, &ttkArrayEditor::Modified);
31 } else {
32 this->ArraySelections[cc] = nullptr;
33 }
34 }
35}
36
38
39vtkDataArraySelection *ttkArrayEditor::GetArraySelection(int association) {
40 if(association >= 0 && association < vtkDataObject::NUMBER_OF_ASSOCIATIONS) {
41 return this->ArraySelections[association];
42 }
43
44 return nullptr;
45}
46
47int ttkArrayEditor::FillInputPortInformation(int port, vtkInformation *info) {
48 if(port == 0 || port == 1) {
49 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject");
50 if(port == 1)
51 info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
52 return 1;
53 }
54 return 0;
55}
56
57int ttkArrayEditor::FillOutputPortInformation(int port, vtkInformation *info) {
58 if(port == 0) {
60 return 1;
61 }
62 return 0;
63}
64
65template <typename VTK_T1, typename VTK_T2>
66int copyArrayData(vtkDataArray *target, vtkDataArray *copy) {
67 auto targetData = ttkUtils::GetPointer<VTK_T1>(target);
68 auto copyData = ttkUtils::GetPointer<VTK_T2>(copy);
69 for(size_t i = 0, n = target->GetNumberOfValues(); i < n; i++) {
70 // NOLINTNEXTLINE (bugprone-signed-char-misuse)
71 copyData[i] = (VTK_T2)(targetData[i]);
72 }
73 return 1;
74}
75
76// =============================================================================
77// RequestData
78// =============================================================================
79int ttkArrayEditor::RequestData(vtkInformation *ttkNotUsed(request),
80 vtkInformationVector **inputVector,
81 vtkInformationVector *outputVector) {
82
83 std::string const associationNames[3] = {"point", "cell", "field"};
84
85 // Pass Input to Output
86 auto target = vtkDataObject::GetData(inputVector[0], 0);
87 auto output = vtkDataObject::GetData(outputVector, 0);
88 output->ShallowCopy(target);
89
90 // switch based on mode
91 ttk::Timer t;
92
93 switch(this->EditorMode) {
95 this->printMsg("Input string: '" + this->DataString + "'",
97
98 // From Data std::string
99 if(this->DataString.length() > 0) {
100
101 // get target attribute
102 int const targetAssociation
103 = this->TargetAssociation < 0 ? 2 : this->TargetAssociation;
104 auto outputAtt = output->GetAttributesAsFieldData(targetAssociation);
105 if(!outputAtt) {
106 this->printErr("Target does not have requested attribute type.");
107 return 0;
108 }
109
110 // if set to automatic then add to field data
111 this->printMsg("Adding parsed arrays from string to "
112 + associationNames[targetAssociation] + " data",
114
115 std::string finalExpressionString;
116 {
117 std::string errorMsg;
118 if(!ttkUtils::replaceVariables(this->DataString,
119 output->GetFieldData(),
120 finalExpressionString, errorMsg)) {
121 std::stringstream const msg;
122 this->printErr(errorMsg);
123 return 0;
124 }
125 }
126
127 // Convert each line to a vtkDataArray
128 {
129 std::stringstream ss(finalExpressionString);
130 std::string line;
131 while(getline(ss, line, '\n')) {
132 auto array = ttkUtils::csvToVtkArray(line);
133 if(!array)
134 return 0;
135
136 if(this->ReplaceExistingArrays
137 || !outputAtt->HasArray(array->GetName()))
138 outputAtt->AddArray(array);
139 }
140 }
141
142 this->printMsg("Adding parsed arrays from string to "
143 + associationNames[targetAssociation] + " data",
144 1, t.getElapsedTime());
145 }
146 break;
147 }
148
151 const bool isAddMode = this->EditorMode == MODE::ADD_ARRAYS_FROM_SOURCE;
152 const std::string modeS
153 = isAddMode ? "Adding point/cell/field arrays from source"
154 : "Filter point/cell/field arrays from source";
156
157 auto source = vtkDataObject::GetData(inputVector[1], 0);
158 if(!source) {
159 this->printErr("Unable to retrieve source vtkDataObject.");
160 return 0;
161 }
162
163 for(int association = 0;
164 association < vtkDataObject::NUMBER_OF_ASSOCIATIONS; ++association) {
165 if(association == vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS)
166 continue;
167
168 // get source attributes and array selection
169 auto sourceFD = source->GetAttributesAsFieldData(association);
170 auto selection = this->GetArraySelection(association);
171 if(!sourceFD || !selection)
172 continue;
173
174 // get target attribute
175 int const targetAssociation
176 = this->TargetAssociation < 0 ? association : this->TargetAssociation;
177 auto outputAtt = output->GetAttributesAsFieldData(targetAssociation);
178 if(!outputAtt) {
179 continue;
180 }
181
182 // add/remove source arrays
183 for(int i = 0; i < sourceFD->GetNumberOfArrays(); i++) {
184 auto array = sourceFD->GetAbstractArray(i);
185
186 if(isAddMode) {
187 if(selection->ArrayIsEnabled(array->GetName()))
188 outputAtt->AddArray(array);
189 } else {
190 if(!selection->ArrayIsEnabled(array->GetName()))
191 outputAtt->RemoveArray(array->GetName());
192 }
193 }
194 }
195
196 this->printMsg(modeS, 1, t.getElapsedTime());
197 break;
198 }
199
200 case MODE::EDIT_ARRAY: {
201
202 auto targetArray = this->GetInputArrayToProcess(0, inputVector);
203 if(!targetArray)
204 return !this->printErr("Unable to retrieve input array.");
205
206 int const targetArrayAssociation
207 = this->GetInputArrayAssociation(0, inputVector);
208
209 this->printMsg("Editing '" + std::string(targetArray->GetName()) + "' "
210 + associationNames[targetArrayAssociation]
211 + " data array",
213
215 // check if it is necessary to create a new array
216 if(this->TargetArrayType >= 0 || this->TargetArrayIndexation[0] >= 0
217 || this->TargetArrayIndexation[1] >= 0) {
218 copy
219 = vtkSmartPointer<vtkDataArray>::Take(vtkDataArray::CreateDataArray(
220 this->TargetArrayType < 0 ? targetArray->GetDataType()
221 : this->TargetArrayType));
222
223 size_t const nComponents = this->TargetArrayIndexation[1] >= 0
224 ? this->TargetArrayIndexation[1]
225 : this->TargetArrayIndexation[0] >= 0
226 ? targetArray->GetNumberOfValues()
227 / this->TargetArrayIndexation[0]
228 : targetArray->GetNumberOfComponents();
229
230 size_t const nTuples = this->TargetArrayIndexation[0] >= 0
231 ? this->TargetArrayIndexation[0]
232 : this->TargetArrayIndexation[1] >= 0
233 ? targetArray->GetNumberOfValues()
234 / this->TargetArrayIndexation[1]
235 : targetArray->GetNumberOfTuples();
236 copy->Allocate(nTuples * nComponents);
237 copy->SetNumberOfComponents(nComponents);
238 copy->SetNumberOfTuples(nTuples);
239
240 switch(vtkTemplate2PackMacro(
241 targetArray->GetDataType(), copy->GetDataType())) {
242 vtkTemplate2Macro((copyArrayData<VTK_T1, VTK_T2>(targetArray, copy)));
243 }
244 } else {
245 copy = vtkSmartPointer<vtkDataArray>::Take(targetArray->NewInstance());
246 copy->ShallowCopy(targetArray);
247 }
248 copy->SetName(this->TargetArrayName.compare("") == 0
249 ? targetArray->GetName()
250 : this->TargetArrayName.data());
251
252 // get target attribute
253 int const targetAssociation = this->TargetAssociation < 0
254 ? targetArrayAssociation
255 : this->TargetAssociation;
256 auto outputAtt = output->GetAttributesAsFieldData(targetAssociation);
257 if(!outputAtt) {
258 this->printErr("Target does not have requested attribute type.");
259 return 0;
260 }
261 outputAtt->AddArray(copy);
262
263 this->printMsg("Editing '" + std::string(targetArray->GetName()) + "' "
264 + associationNames[targetArrayAssociation]
265 + " data array",
266 1, t.getElapsedTime());
267 break;
268 }
269
270 default: {
271 this->printErr("Unsupported Mode");
272 return 0;
273 }
274 }
275
276 return 1;
277}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
static vtkInformationIntegerKey * SAME_DATA_TYPE_AS_INPUT_PORT()
TTK VTK-filter that edit arrays of a vtkDataObject.
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
vtkDataArraySelection * GetArraySelection(int association)
~ttkArrayEditor() override
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
static int replaceVariables(const std::string &iString, vtkFieldData *fieldData, std::string &oString, std::string &errorMsg)
Definition ttkUtils.cpp:73
static vtkSmartPointer< vtkAbstractArray > csvToVtkArray(const std::string &line)
Definition ttkUtils.cpp:152
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
double getElapsedTime()
Definition Timer.h:15
int copyArrayData(vtkDataArray *target, vtkDataArray *copy)
vtkStandardNewMacro(ttkArrayEditor)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)