TTK
Loading...
Searching...
No Matches
ttkUtils.cpp
Go to the documentation of this file.
1#include <ttkUtils.h>
2
3#include <vtkAbstractArray.h>
4#include <vtkCellArray.h>
5#include <vtkDoubleArray.h>
6#include <vtkFieldData.h>
7#include <vtkIdTypeArray.h>
8#include <vtkNew.h>
9#include <vtkPoints.h>
10#include <vtkPolyData.h>
11#include <vtkSmartPointer.h>
12#include <vtkStringArray.h>
13#include <vtkUnstructuredGrid.h>
14
15#include <iostream>
16
17#ifdef TTK_ENABLE_MPI_TIME
18#include <mpi.h>
19#endif
20int ttkUtils::replaceVariable(const std::string &iString,
21 vtkFieldData *fieldData,
22 std::string &oString,
23 std::string &errorMsg) {
24 std::string varName = iString;
25 int varIndex = -1;
26 bool varIndexDefined = false;
27
28 // Check if varIndex is specified
29 size_t const indexDelimiter0 = iString.find('[');
30 size_t const indexDelimiter1 = iString.find(']');
31 if(indexDelimiter0 != std::string::npos
32 && indexDelimiter1 != std::string::npos) {
33 if(indexDelimiter0 > indexDelimiter1
34 || iString.find('[', indexDelimiter0 + 1) != std::string::npos
35 || iString.find('}', indexDelimiter1 + 1) != std::string::npos) {
36 errorMsg = "Invalid Syntax:\n" + iString;
37 return 0;
38 }
39
40 varName = iString.substr(0, indexDelimiter0);
41 varIndex = stoi(iString.substr(
42 indexDelimiter0 + 1, indexDelimiter1 - indexDelimiter0 - 1));
43 varIndexDefined = true;
44 }
45
46 // Search in candidates
47 auto column = fieldData->GetAbstractArray(varName.data());
48 if(column == nullptr) {
49 errorMsg = "FieldData does not contain array '" + varName + "'";
50 return 0;
51 }
52
53 size_t const n = column->GetNumberOfTuples();
54 size_t const m = column->GetNumberOfComponents();
55 int const s = n * m;
56
57 if(!varIndexDefined) {
58 if(s > 0) {
59 oString = column->GetVariantValue(0).ToString();
60 for(int i = 1; i < s; i++)
61 oString += "," + column->GetVariantValue(i).ToString();
62 }
63 } else {
64 if(varIndex < 0 || varIndex >= s) {
65 errorMsg = "Index " + std::to_string(varIndex) + "/" + std::to_string(s)
66 + " for FieldData Array '" + varName + "' out of range";
67 return 0;
68 }
69 oString = column->GetVariantValue(varIndex).ToString();
70 }
71
72 return 1;
73}
74
75int ttkUtils::replaceVariables(const std::string &iString,
76 vtkFieldData *fieldData,
77 std::string &oString,
78 std::string &errorMsg) {
79 oString = iString;
80
81 while(oString.find('{') != std::string::npos
82 && oString.find('}') != std::string::npos) {
83 size_t o = oString.find('{');
84 size_t const c = oString.find('}');
85 // {...{....{...}...}..}
86 // | |
87 // o c
88
89 size_t oNext = oString.find('{', o + 1);
90 while(oNext != std::string::npos && oNext < c) {
91 o = oNext;
92 oNext = oString.find('{', o + 1);
93 }
94
95 // {...{....{var}...}..}
96 // | |
97 // o c
98 std::string const var = oString.substr(o + 1, c - 1 - o);
99
100 std::string rVar;
101 if(!replaceVariable(var, fieldData, rVar, errorMsg))
102 return 0;
103
104 oString = oString.substr(0, o).append(rVar).append(
105 oString.substr(c + 1, oString.length() - c - 1));
106 }
107
108 if(oString.find('{') != std::string::npos
109 || oString.find('}') != std::string::npos) {
110 errorMsg = "Invalid Syntax:\n" + iString;
111 return 0;
112 }
113
114 return 1;
115}
116
117int ttkUtils::stringListToVector(const std::string &iString,
118 std::vector<std::string> &v) {
119 // ...,...,....,
120 // | |
121 // i j
122 size_t i = 0;
123 size_t j = iString.find(',');
124 while(j != std::string::npos) {
125 v.push_back(iString.substr(i, j - i));
126 i = j + 1;
127 j = iString.find(',', i);
128 }
129 if(iString.length() > i)
130 v.push_back(iString.substr(i, iString.length() - i));
131
132 return 1;
133}
134
135int ttkUtils::stringListToDoubleVector(const std::string &iString,
136 std::vector<double> &v) {
137 std::vector<std::string> stringVector;
138 if(!ttkUtils::stringListToVector(iString, stringVector))
139 return 0;
140
141 size_t const n = stringVector.size();
142 v.resize(n);
143 // try {
144 for(size_t i = 0; i < n; i++)
145 v[i] = stod(stringVector[i]);
146 // } catch(std::invalid_argument &e) {
147 // return 0;
148 // }
149
150 return 1;
151}
152
154 ttkUtils::csvToVtkArray(const std::string &line) {
155 size_t const firstComma = line.find(',', 0);
156
157 if(firstComma == std::string::npos)
158 return nullptr;
159
160 std::string const arrayName = line.substr(0, firstComma);
161
162 std::vector<std::string> valuesAsString;
164 line.substr(firstComma + 1, std::string::npos), valuesAsString);
165 size_t const nValues = valuesAsString.size();
166 if(nValues < 1)
167 return nullptr;
168
169 // Check if all elements are numbers
170 bool isNumeric = true;
171
172 std::vector<double> valuesAsDouble(nValues);
173 try {
174 for(size_t i = 0; i < nValues; i++)
175 valuesAsDouble[i] = std::stod(valuesAsString[i]);
176 } catch(const std::invalid_argument &) {
177 isNumeric = false;
178 } catch(const std::out_of_range &) {
179 isNumeric = false;
180 }
181
182 if(isNumeric) {
184 array->SetName(arrayName.data());
185 array->SetNumberOfValues(nValues);
186 for(size_t i = 0; i < nValues; i++)
187 array->SetValue(i, valuesAsDouble[i]);
188 return array;
189 } else {
191 array->SetName(arrayName.data());
192 array->SetNumberOfValues(nValues);
193 for(size_t i = 0; i < nValues; i++)
194 array->SetValue(i, valuesAsString[i]);
195 return array;
196 }
197}
198
200 ttkUtils::csvToDoubleArray(const std::string &line) {
201 size_t const firstComma = line.find(',', 0);
202
203 if(firstComma == std::string::npos)
204 return nullptr;
205
206 std::string const arrayName = line.substr(0, firstComma);
207 std::string const valuesAsString
208 = line.substr(firstComma + 1, std::string::npos);
209
210 std::vector<double> values;
211 ttkUtils::stringListToDoubleVector(valuesAsString, values);
212 size_t const n = values.size();
213
215 array->SetName(arrayName.data());
216 array->SetNumberOfComponents(1);
217 array->SetNumberOfTuples(n);
218 auto arrayData = reinterpret_cast<double *>(GetVoidPointer(array));
219 for(size_t i = 0; i < n; i++)
220 arrayData[i] = values[i];
221
222 return array;
223}
224
228void *ttkUtils::GetVoidPointer(vtkDataArray *array, vtkIdType start) {
229 void *outPtr = nullptr;
230 if(array == nullptr)
231 return outPtr;
232
233 switch(array->GetDataType()) {
234 vtkTemplateMacro(
235 auto *aosArray = vtkAOSDataArrayTemplate<VTK_TT>::FastDownCast(array);
236 if(aosArray) { outPtr = aosArray->GetVoidPointer(start); });
237 }
238 return outPtr;
239}
240
241void *ttkUtils::GetVoidPointer(vtkPoints *points, vtkIdType start) {
242 return GetVoidPointer(points->GetData(), start);
243}
244
246 vtkIdType idx) {
247 auto slicedArray
248 = vtkSmartPointer<vtkAbstractArray>::Take(array->NewInstance());
249 slicedArray->SetName(array->GetName());
250 slicedArray->SetNumberOfComponents(array->GetNumberOfComponents());
251 slicedArray->SetNumberOfTuples(1);
252 slicedArray->SetTuple(0, idx, array);
253 return slicedArray;
254}
255
256void *ttkUtils::WriteVoidPointer(vtkDataArray *array,
257 vtkIdType valueIdx,
258 vtkIdType numValues) {
259 void *outPtr = nullptr;
260 switch(array->GetDataType()) {
261 vtkTemplateMacro(auto *aosArray
262 = vtkAOSDataArrayTemplate<VTK_TT>::FastDownCast(array);
263 if(aosArray) {
264 outPtr = aosArray->WriteVoidPointer(valueIdx, numValues);
265 });
266 }
267 return outPtr;
268}
269
270void *ttkUtils::WritePointer(vtkDataArray *array,
271 vtkIdType valueIdx,
272 vtkIdType numValues) {
273 void *outPtr = nullptr;
274 switch(array->GetDataType()) {
275 vtkTemplateMacro(
276 auto *aosArray = vtkAOSDataArrayTemplate<VTK_TT>::FastDownCast(array);
277 if(aosArray) { outPtr = aosArray->WritePointer(valueIdx, numValues); });
278 }
279 return outPtr;
280}
281
282void ttkUtils::SetVoidArray(vtkDataArray *array,
283 void *data,
284 vtkIdType size,
285 int save) {
286
287 switch(array->GetDataType()) {
288 vtkTemplateMacro(
289 auto *aosArray = vtkAOSDataArrayTemplate<VTK_TT>::FastDownCast(array);
290 if(aosArray) { aosArray->SetVoidArray(data, size, save); } else {
291 std::cerr << "SetVoidArray on incompatible vtkDataArray:" << endl;
292 array->Print(std::cerr);
293 });
294 }
295}
296
297[[deprecated]] void ttkUtils::FillCellArrayFromSingle(vtkIdType const *cells,
298 vtkIdType ncells,
299 vtkCellArray *cellArray) {
300 size_t curPos = 0;
301 vtkNew<vtkIdList> verts;
302 for(vtkIdType cid = 0; cid < ncells; cid++) {
303 const vtkIdType nbVerts = cells[curPos];
304 verts->SetNumberOfIds(nbVerts);
305 curPos++;
306 for(vtkIdType v = 0; v < nbVerts; v++) {
307 verts->SetId(v, cells[curPos]);
308 curPos++;
309 }
310 cellArray->InsertNextCell(verts);
311 }
312}
313
314void ttkUtils::FillCellArrayFromDual(vtkIdType const *cells_co,
315 vtkIdType const *cells_off,
316 vtkIdType ncells,
317 vtkCellArray *cellArray) {
318 size_t curPos = 0;
319 vtkNew<vtkIdList> verts;
320 for(vtkIdType cid = 0; cid < ncells; cid++) {
321 const vtkIdType nbVerts = cells_off[cid + 1] - cells_off[cid];
322 verts->SetNumberOfIds(nbVerts);
323 for(vtkIdType v = 0; v < nbVerts; v++) {
324 verts->SetId(v, cells_co[curPos]);
325 curPos++;
326 }
327 cellArray->InsertNextCell(verts);
328 }
329}
330
331int ttkUtils::CellVertexFromPoints(vtkDataSet *const dataSet,
332 vtkPoints *const points) {
333
334 if(dataSet == nullptr || points == nullptr) {
335 return 0;
336 }
337
338 if(!dataSet->IsA("vtkUnstructuredGrid") && !dataSet->IsA("vtkPolyData")) {
339 return 0;
340 }
341
342 const size_t nPoints = points->GetNumberOfPoints();
343 if(nPoints == 0) {
344 return 0;
345 }
346
347 vtkNew<vtkIdTypeArray> offsets{};
348 offsets->SetNumberOfTuples(nPoints + 1);
349 auto offsetsData = ttkUtils::GetPointer<vtkIdType>(offsets);
350 for(size_t i = 0; i <= nPoints; i++)
351 offsetsData[i] = i;
352
353 vtkNew<vtkIdTypeArray> connectivity{};
354 connectivity->SetNumberOfTuples(nPoints);
355 auto connectivityData = ttkUtils::GetPointer<vtkIdType>(connectivity);
356 for(size_t i = 0; i < nPoints; i++)
357 connectivityData[i] = i;
358
359 vtkNew<vtkCellArray> cells{};
360 cells->SetData(offsets, connectivity);
361
362 if(dataSet->IsA("vtkUnstructuredGrid")) {
363 const auto vtu{vtkUnstructuredGrid::SafeDownCast(dataSet)};
364 if(vtu != nullptr) {
365 vtu->SetPoints(points);
366 vtu->SetCells(VTK_VERTEX, cells);
367 }
368 } else if(dataSet->IsA("vtkPolyData")) {
369 const auto vtp{vtkPolyData::SafeDownCast(dataSet)};
370 if(vtp != nullptr) {
371 vtp->SetPoints(points);
372 vtp->SetVerts(cells);
373 }
374 }
375
376 return 1;
377}
static int replaceVariables(const std::string &iString, vtkFieldData *fieldData, std::string &oString, std::string &errorMsg)
Definition ttkUtils.cpp:75
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
Definition ttkUtils.cpp:228
static int stringListToDoubleVector(const std::string &iString, std::vector< double > &v)
Definition ttkUtils.cpp:135
static vtkSmartPointer< vtkAbstractArray > SliceArray(vtkAbstractArray *array, vtkIdType idx)
Definition ttkUtils.cpp:245
static void FillCellArrayFromSingle(vtkIdType const *cells, vtkIdType ncells, vtkCellArray *cellArray)
Definition ttkUtils.cpp:297
static void * WritePointer(vtkDataArray *array, vtkIdType start, vtkIdType numValues)
Definition ttkUtils.cpp:270
static int replaceVariable(const std::string &iString, vtkFieldData *fieldData, std::string &oString, std::string &errorMsg)
Definition ttkUtils.cpp:20
static int CellVertexFromPoints(vtkDataSet *const dataSet, vtkPoints *const points)
Definition ttkUtils.cpp:331
static vtkSmartPointer< vtkAbstractArray > csvToVtkArray(const std::string &line)
Definition ttkUtils.cpp:154
static vtkSmartPointer< vtkDoubleArray > csvToDoubleArray(const std::string &line)
Definition ttkUtils.cpp:200
static void FillCellArrayFromDual(vtkIdType const *cells_co, vtkIdType const *cells_off, vtkIdType ncells, vtkCellArray *cellArray)
Definition ttkUtils.cpp:314
static DT * GetPointer(vtkDataArray *array, vtkIdType start=0)
Definition ttkUtils.h:59
static void SetVoidArray(vtkDataArray *array, void *data, vtkIdType size, int save)
Definition ttkUtils.cpp:282
static void * WriteVoidPointer(vtkDataArray *array, vtkIdType start, vtkIdType numValues)
Definition ttkUtils.cpp:256
static int stringListToVector(const std::string &iString, std::vector< std::string > &v)
Definition ttkUtils.cpp:117