1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkFieldDataToAttributeDataFilter.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkFieldDataToAttributeDataFilter.h"
16
17 #include "vtkCellData.h"
18 #include "vtkDataArray.h"
19 #include "vtkDataSet.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24 #include "vtkStreamingDemandDrivenPipeline.h"
25
26 vtkStandardNewMacro(vtkFieldDataToAttributeDataFilter);
27
28 // Instantiate object with no input and no defined output.
vtkFieldDataToAttributeDataFilter()29 vtkFieldDataToAttributeDataFilter::vtkFieldDataToAttributeDataFilter()
30 {
31 int i;
32
33 this->InputField = VTK_DATA_OBJECT_FIELD;
34 this->OutputAttributeData = VTK_POINT_DATA;
35 this->DefaultNormalize = 0;
36
37 this->NumberOfScalarComponents = 0;
38 for (i = 0; i < 4; i++)
39 {
40 this->ScalarArrays[i] = nullptr;
41 this->ScalarArrayComponents[i] = -1; // uninitialized
42 this->ScalarComponentRange[i][0] = this->ScalarComponentRange[i][1] = -1;
43 this->ScalarNormalize[i] = 1; // yes, normalize
44 }
45
46 for (i = 0; i < 3; i++)
47 {
48 this->VectorArrays[i] = nullptr;
49 this->VectorArrayComponents[i] = -1; // uninitialized
50 this->VectorComponentRange[i][0] = this->VectorComponentRange[i][1] = -1;
51 this->VectorNormalize[i] = 1; // yes, normalize
52 }
53
54 for (i = 0; i < 3; i++)
55 {
56 this->NormalArrays[i] = nullptr;
57 this->NormalArrayComponents[i] = -1; // uninitialized
58 this->NormalComponentRange[i][0] = this->NormalComponentRange[i][1] = -1;
59 this->NormalNormalize[i] = 1; // yes, normalize
60 }
61
62 this->NumberOfTCoordComponents = 0;
63 for (i = 0; i < 3; i++)
64 {
65 this->TCoordArrays[i] = nullptr;
66 this->TCoordArrayComponents[i] = -1; // uninitialized
67 this->TCoordComponentRange[i][0] = this->TCoordComponentRange[i][1] = -1;
68 this->TCoordNormalize[i] = 1; // yes, normalize
69 }
70
71 for (i = 0; i < 9; i++)
72 {
73 this->TensorArrays[i] = nullptr;
74 this->TensorArrayComponents[i] = -1; // uninitialized
75 this->TensorComponentRange[i][0] = this->TensorComponentRange[i][1] = -1;
76 this->TensorNormalize[i] = 1; // yes, normalize
77 }
78 }
79
~vtkFieldDataToAttributeDataFilter()80 vtkFieldDataToAttributeDataFilter::~vtkFieldDataToAttributeDataFilter()
81 {
82 int i;
83
84 for (i = 0; i < 4; i++)
85 {
86 delete[] this->ScalarArrays[i];
87 }
88
89 for (i = 0; i < 3; i++)
90 {
91 delete[] this->VectorArrays[i];
92 }
93
94 for (i = 0; i < 3; i++)
95 {
96 delete[] this->NormalArrays[i];
97 }
98
99 for (i = 0; i < 3; i++)
100 {
101 delete[] this->TCoordArrays[i];
102 }
103
104 for (i = 0; i < 9; i++)
105 {
106 delete[] this->TensorArrays[i];
107 }
108 }
109
110 // Stuff related to filter interface------------------------------------------
111 //
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)112 int vtkFieldDataToAttributeDataFilter::RequestData(vtkInformation* vtkNotUsed(request),
113 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
114 {
115 // get the info objects
116 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
117 vtkInformation* outInfo = outputVector->GetInformationObject(0);
118
119 // get the input and output
120 vtkDataSet* input = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
121 vtkDataSet* output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
122
123 vtkIdType num;
124 vtkDataSetAttributes* attr;
125 vtkFieldData* fd;
126 vtkDebugMacro(<< "Generating attribute data from field data");
127
128 // First, copy the input to the output as a starting point
129 output->CopyStructure(input);
130
131 // Pass here so that the attributes/fields can be over-written later
132 output->GetPointData()->PassData(input->GetPointData());
133 output->GetCellData()->PassData(input->GetCellData());
134
135 if (this->OutputAttributeData == VTK_CELL_DATA)
136 {
137 attr = output->GetCellData();
138 num = input->GetNumberOfCells();
139 }
140 else
141 {
142 attr = output->GetPointData();
143 num = input->GetNumberOfPoints();
144 }
145
146 if (num < 1)
147 {
148 vtkDebugMacro(<< "No input points/cells to create attribute data for");
149 return 1;
150 }
151
152 fd = nullptr;
153 if (this->InputField == VTK_DATA_OBJECT_FIELD)
154 {
155 fd = input->GetFieldData();
156 }
157 else if (this->InputField == VTK_POINT_DATA_FIELD)
158 {
159 fd = input->GetPointData();
160 }
161 else if (this->InputField == VTK_CELL_DATA_FIELD)
162 {
163 fd = input->GetCellData();
164 }
165 if (fd == nullptr)
166 {
167 vtkErrorMacro(<< "No field data available");
168 return 1;
169 }
170
171 this->ConstructScalars(num, fd, attr, this->ScalarComponentRange, this->ScalarArrays,
172 this->ScalarArrayComponents, this->ScalarNormalize, this->NumberOfScalarComponents);
173 this->ConstructVectors(num, fd, attr, this->VectorComponentRange, this->VectorArrays,
174 this->VectorArrayComponents, this->VectorNormalize);
175 this->ConstructTensors(num, fd, attr, this->TensorComponentRange, this->TensorArrays,
176 this->TensorArrayComponents, this->TensorNormalize);
177 this->ConstructTCoords(num, fd, attr, this->TCoordComponentRange, this->TCoordArrays,
178 this->TCoordArrayComponents, this->TCoordNormalize, this->NumberOfTCoordComponents);
179 this->ConstructNormals(num, fd, attr, this->NormalComponentRange, this->NormalArrays,
180 this->NormalArrayComponents, this->NormalNormalize);
181 this->ConstructFieldData(num, attr);
182
183 return 1;
184 }
185
PrintSelf(ostream & os,vtkIndent indent)186 void vtkFieldDataToAttributeDataFilter::PrintSelf(ostream& os, vtkIndent indent)
187 {
188 this->Superclass::PrintSelf(os, indent);
189
190 os << indent << "Input Field: ";
191 if (this->InputField == VTK_DATA_OBJECT_FIELD)
192 {
193 os << "DataObjectField\n";
194 }
195 else if (this->InputField == VTK_POINT_DATA_FIELD)
196 {
197 os << "PointDataField\n";
198 }
199 else // if ( this->InputField == VTK_CELL_DATA_FIELD )
200 {
201 os << "CellDataField\n";
202 }
203
204 os << indent << "Default Normalize: " << (this->DefaultNormalize ? "On\n" : "Off\n");
205
206 os << indent << "Output Attribute Data: ";
207 if (this->OutputAttributeData == VTK_CELL_DATA)
208 {
209 os << "CellData\n";
210 }
211 else // if ( this->OutputAttributeData == VTK_POINT_DATA )
212 {
213 os << "PointData\n";
214 }
215 }
216
217 // Stuff related to scalars --------------------------------------------
218 //
SetScalarComponent(int comp,const char * arrayName,int arrayComp,int min,int max,int normalize)219 void vtkFieldDataToAttributeDataFilter::SetScalarComponent(
220 int comp, const char* arrayName, int arrayComp, int min, int max, int normalize)
221 {
222 if (comp < 0 || comp > 3)
223 {
224 vtkErrorMacro(<< "Scalar component must be between (0,3)");
225 return;
226 }
227
228 if (comp >= this->NumberOfScalarComponents)
229 {
230 this->NumberOfScalarComponents = comp + 1;
231 }
232 vtkFieldDataToAttributeDataFilter::SetArrayName(this, this->ScalarArrays[comp], arrayName);
233 if (this->ScalarArrayComponents[comp] != arrayComp)
234 {
235 this->ScalarArrayComponents[comp] = arrayComp;
236 this->Modified();
237 }
238 if (this->ScalarComponentRange[comp][0] != min)
239 {
240 this->ScalarComponentRange[comp][0] = min;
241 this->Modified();
242 }
243 if (this->ScalarComponentRange[comp][1] != max)
244 {
245 this->ScalarComponentRange[comp][1] = max;
246 this->Modified();
247 }
248 if (this->ScalarNormalize[comp] != normalize)
249 {
250 this->ScalarNormalize[comp] = normalize;
251 this->Modified();
252 }
253 }
254
GetScalarComponentArrayName(int comp)255 const char* vtkFieldDataToAttributeDataFilter::GetScalarComponentArrayName(int comp)
256 {
257 comp = (comp < 0 ? 0 : (comp > 3 ? 3 : comp));
258 return this->ScalarArrays[comp];
259 }
260
GetScalarComponentArrayComponent(int comp)261 int vtkFieldDataToAttributeDataFilter::GetScalarComponentArrayComponent(int comp)
262 {
263 comp = (comp < 0 ? 0 : (comp > 3 ? 3 : comp));
264 return this->ScalarArrayComponents[comp];
265 }
266
GetScalarComponentMinRange(int comp)267 int vtkFieldDataToAttributeDataFilter::GetScalarComponentMinRange(int comp)
268 {
269 comp = (comp < 0 ? 0 : (comp > 3 ? 3 : comp));
270 return this->ScalarComponentRange[comp][0];
271 }
272
GetScalarComponentMaxRange(int comp)273 int vtkFieldDataToAttributeDataFilter::GetScalarComponentMaxRange(int comp)
274 {
275 comp = (comp < 0 ? 0 : (comp > 3 ? 3 : comp));
276 return this->ScalarComponentRange[comp][1];
277 }
278
GetScalarComponentNormalizeFlag(int comp)279 int vtkFieldDataToAttributeDataFilter::GetScalarComponentNormalizeFlag(int comp)
280 {
281 comp = (comp < 0 ? 0 : (comp > 3 ? 3 : comp));
282 return this->ScalarNormalize[comp];
283 }
284
ConstructScalars(int num,vtkFieldData * fd,vtkDataSetAttributes * attr,vtkIdType componentRange[4][2],char * arrays[4],int arrayComp[4],int normalize[4],int numComp)285 void vtkFieldDataToAttributeDataFilter::ConstructScalars(int num, vtkFieldData* fd,
286 vtkDataSetAttributes* attr, vtkIdType componentRange[4][2], char* arrays[4], int arrayComp[4],
287 int normalize[4], int numComp)
288 {
289 int i, normalizeAny, updated = 0;
290 vtkDataArray* fieldArray[4];
291
292 if (numComp < 1)
293 {
294 return;
295 }
296 for (i = 0; i < numComp; i++)
297 {
298 if (arrays[i] == nullptr)
299 {
300 return;
301 }
302 }
303
304 for (i = 0; i < numComp; i++)
305 {
306 fieldArray[i] = vtkFieldDataToAttributeDataFilter::GetFieldArray(fd, arrays[i], arrayComp[i]);
307
308 if (fieldArray[i] == nullptr)
309 {
310 vtkErrorMacro(<< "Can't find array/component requested");
311 return;
312 }
313 }
314
315 for (normalizeAny = i = 0; i < numComp; i++)
316 {
317 updated |=
318 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[i], componentRange[i]);
319 if (num != (componentRange[i][1] - componentRange[i][0] + 1))
320 {
321 vtkErrorMacro(<< "Number of scalars not consistent");
322 return;
323 }
324 normalizeAny |= normalize[i];
325 }
326
327 vtkDataArray* newScalars;
328 for (i = 1; i < numComp; i++) // see whether all the data is from the same array
329 {
330 if (fieldArray[i] != fieldArray[i - 1])
331 {
332 break;
333 }
334 }
335
336 // see whether we can reuse the data array from the field
337 if (i >= numComp && fieldArray[0]->GetNumberOfComponents() == numComp &&
338 fieldArray[0]->GetNumberOfTuples() == num && !normalizeAny)
339 {
340 newScalars = fieldArray[0];
341 newScalars->Register(nullptr);
342 }
343 else // have to copy data into created array
344 {
345 newScalars = vtkDataArray::CreateDataArray(
346 vtkFieldDataToAttributeDataFilter::GetComponentsType(numComp, fieldArray));
347 newScalars->SetNumberOfTuples(num);
348
349 for (i = 0; i < numComp; i++)
350 {
351 if (vtkFieldDataToAttributeDataFilter::ConstructArray(newScalars, i, fieldArray[i],
352 arrayComp[i], componentRange[i][0], componentRange[i][1], normalize[i]) == 0)
353 {
354 newScalars->Delete();
355 return;
356 }
357 }
358 }
359
360 attr->SetScalars(newScalars);
361 newScalars->Delete();
362 if (updated) // reset for next execution pass
363 {
364 for (i = 0; i < numComp; i++)
365 {
366 componentRange[i][0] = componentRange[i][1] = -1;
367 }
368 }
369 }
370
371 // Stuff related to vectors --------------------------------------------
372 //
SetVectorComponent(int comp,const char * arrayName,int arrayComp,int min,int max,int normalize)373 void vtkFieldDataToAttributeDataFilter::SetVectorComponent(
374 int comp, const char* arrayName, int arrayComp, int min, int max, int normalize)
375 {
376 if (comp < 0 || comp > 2)
377 {
378 vtkErrorMacro(<< "Vector component must be between (0,2)");
379 return;
380 }
381
382 vtkFieldDataToAttributeDataFilter::SetArrayName(this, this->VectorArrays[comp], arrayName);
383 if (this->VectorArrayComponents[comp] != arrayComp)
384 {
385 this->VectorArrayComponents[comp] = arrayComp;
386 this->Modified();
387 }
388 if (this->VectorComponentRange[comp][0] != min)
389 {
390 this->VectorComponentRange[comp][0] = min;
391 this->Modified();
392 }
393 if (this->VectorComponentRange[comp][1] != max)
394 {
395 this->VectorComponentRange[comp][1] = max;
396 this->Modified();
397 }
398 if (this->VectorNormalize[comp] != normalize)
399 {
400 this->VectorNormalize[comp] = normalize;
401 this->Modified();
402 }
403 }
404
GetVectorComponentArrayName(int comp)405 const char* vtkFieldDataToAttributeDataFilter::GetVectorComponentArrayName(int comp)
406 {
407 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
408 return this->VectorArrays[comp];
409 }
410
GetVectorComponentArrayComponent(int comp)411 int vtkFieldDataToAttributeDataFilter::GetVectorComponentArrayComponent(int comp)
412 {
413 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
414 return this->VectorArrayComponents[comp];
415 }
416
GetVectorComponentMinRange(int comp)417 int vtkFieldDataToAttributeDataFilter::GetVectorComponentMinRange(int comp)
418 {
419 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
420 return this->VectorComponentRange[comp][0];
421 }
422
GetVectorComponentMaxRange(int comp)423 int vtkFieldDataToAttributeDataFilter::GetVectorComponentMaxRange(int comp)
424 {
425 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
426 return this->VectorComponentRange[comp][1];
427 }
428
GetVectorComponentNormalizeFlag(int comp)429 int vtkFieldDataToAttributeDataFilter::GetVectorComponentNormalizeFlag(int comp)
430 {
431 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
432 return this->VectorNormalize[comp];
433 }
434
ConstructVectors(int num,vtkFieldData * fd,vtkDataSetAttributes * attr,vtkIdType componentRange[3][2],char * arrays[3],int arrayComp[3],int normalize[3])435 void vtkFieldDataToAttributeDataFilter::ConstructVectors(int num, vtkFieldData* fd,
436 vtkDataSetAttributes* attr, vtkIdType componentRange[3][2], char* arrays[3], int arrayComp[3],
437 int normalize[3])
438 {
439 int i, updated;
440 vtkDataArray* fieldArray[3];
441
442 for (i = 0; i < 3; i++)
443 {
444 if (arrays[i] == nullptr)
445 {
446 return;
447 }
448 }
449
450 for (i = 0; i < 3; i++)
451 {
452 fieldArray[i] = vtkFieldDataToAttributeDataFilter::GetFieldArray(fd, arrays[i], arrayComp[i]);
453
454 if (fieldArray[i] == nullptr)
455 {
456 vtkErrorMacro(<< "Can't find array requested");
457 return;
458 }
459 }
460
461 updated =
462 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[0], componentRange[0]);
463 updated |=
464 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[1], componentRange[1]);
465 updated |=
466 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[2], componentRange[2]);
467
468 if (num != (componentRange[0][1] - componentRange[0][0] + 1) ||
469 num != (componentRange[1][1] - componentRange[1][0] + 1) ||
470 num != (componentRange[2][1] - componentRange[2][0] + 1))
471 {
472 vtkErrorMacro(<< "Number of vectors not consistent");
473 return;
474 }
475
476 vtkDataArray* newVectors;
477 if (fieldArray[0]->GetNumberOfComponents() == 3 && fieldArray[0] == fieldArray[1] &&
478 fieldArray[1] == fieldArray[2] && fieldArray[0]->GetNumberOfTuples() == num && !normalize[0] &&
479 !normalize[1] && !normalize[2])
480 {
481 newVectors = fieldArray[0];
482 newVectors->Register(nullptr);
483 }
484 else // have to copy data into created array
485 {
486 newVectors = vtkDataArray::CreateDataArray(
487 vtkFieldDataToAttributeDataFilter::GetComponentsType(3, fieldArray));
488 newVectors->SetNumberOfComponents(3);
489 newVectors->SetNumberOfTuples(num);
490
491 for (i = 0; i < 3; i++)
492 {
493 if (vtkFieldDataToAttributeDataFilter::ConstructArray(newVectors, i, fieldArray[i],
494 arrayComp[i], componentRange[i][0], componentRange[i][1], normalize[i]) == 0)
495 {
496 newVectors->Delete();
497 return;
498 }
499 }
500 }
501
502 attr->SetVectors(newVectors);
503 newVectors->Delete();
504 if (updated) // reset for next execution pass
505 {
506 for (i = 0; i < 3; i++)
507 {
508 componentRange[i][0] = componentRange[i][1] = -1;
509 }
510 }
511 }
512
513 // Stuff related to normals --------------------------------------------
514 //
SetNormalComponent(int comp,const char * arrayName,int arrayComp,int min,int max,int normalize)515 void vtkFieldDataToAttributeDataFilter::SetNormalComponent(
516 int comp, const char* arrayName, int arrayComp, int min, int max, int normalize)
517 {
518 if (comp < 0 || comp > 2)
519 {
520 vtkErrorMacro(<< "Normal component must be between (0,2)");
521 return;
522 }
523
524 vtkFieldDataToAttributeDataFilter::SetArrayName(this, this->NormalArrays[comp], arrayName);
525 if (this->NormalArrayComponents[comp] != arrayComp)
526 {
527 this->NormalArrayComponents[comp] = arrayComp;
528 this->Modified();
529 }
530 if (this->NormalComponentRange[comp][0] != min)
531 {
532 this->NormalComponentRange[comp][0] = min;
533 this->Modified();
534 }
535 if (this->NormalComponentRange[comp][1] != max)
536 {
537 this->NormalComponentRange[comp][1] = max;
538 this->Modified();
539 }
540 if (this->NormalNormalize[comp] != normalize)
541 {
542 this->NormalNormalize[comp] = normalize;
543 this->Modified();
544 }
545 }
546
GetNormalComponentArrayName(int comp)547 const char* vtkFieldDataToAttributeDataFilter::GetNormalComponentArrayName(int comp)
548 {
549 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
550 return this->NormalArrays[comp];
551 }
552
GetNormalComponentArrayComponent(int comp)553 int vtkFieldDataToAttributeDataFilter::GetNormalComponentArrayComponent(int comp)
554 {
555 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
556 return this->NormalArrayComponents[comp];
557 }
558
GetNormalComponentMinRange(int comp)559 int vtkFieldDataToAttributeDataFilter::GetNormalComponentMinRange(int comp)
560 {
561 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
562 return this->NormalComponentRange[comp][0];
563 }
564
GetNormalComponentMaxRange(int comp)565 int vtkFieldDataToAttributeDataFilter::GetNormalComponentMaxRange(int comp)
566 {
567 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
568 return this->NormalComponentRange[comp][1];
569 }
570
GetNormalComponentNormalizeFlag(int comp)571 int vtkFieldDataToAttributeDataFilter::GetNormalComponentNormalizeFlag(int comp)
572 {
573 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
574 return this->NormalNormalize[comp];
575 }
576
ConstructNormals(int num,vtkFieldData * fd,vtkDataSetAttributes * attr,vtkIdType componentRange[3][2],char * arrays[3],int arrayComp[3],int normalize[3])577 void vtkFieldDataToAttributeDataFilter::ConstructNormals(int num, vtkFieldData* fd,
578 vtkDataSetAttributes* attr, vtkIdType componentRange[3][2], char* arrays[3], int arrayComp[3],
579 int normalize[3])
580 {
581 int i, updated;
582 vtkDataArray* fieldArray[3];
583
584 for (i = 0; i < 3; i++)
585 {
586 if (arrays[i] == nullptr)
587 {
588 return;
589 }
590 }
591
592 for (i = 0; i < 3; i++)
593 {
594 fieldArray[i] = vtkFieldDataToAttributeDataFilter::GetFieldArray(fd, arrays[i], arrayComp[i]);
595
596 if (fieldArray[i] == nullptr)
597 {
598 vtkErrorMacro(<< "Can't find array requested");
599 return;
600 }
601 }
602
603 updated =
604 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[0], componentRange[0]);
605 updated |=
606 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[1], componentRange[1]);
607 updated |=
608 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[2], componentRange[2]);
609
610 if (num != (componentRange[0][1] - componentRange[0][0] + 1) ||
611 num != (componentRange[1][1] - componentRange[1][0] + 1) ||
612 num != (componentRange[2][1] - componentRange[2][0] + 1))
613 {
614 vtkErrorMacro(<< "Number of normals not consistent");
615 return;
616 }
617
618 vtkDataArray* newNormals;
619 if (fieldArray[0]->GetNumberOfComponents() == 3 && fieldArray[0] == fieldArray[1] &&
620 fieldArray[1] == fieldArray[2] && fieldArray[0]->GetNumberOfTuples() == num && !normalize[0] &&
621 !normalize[1] && !normalize[2])
622 {
623 newNormals = fieldArray[0];
624 newNormals->Register(nullptr);
625 }
626 else // have to copy data into created array
627 {
628 newNormals = vtkDataArray::CreateDataArray(
629 vtkFieldDataToAttributeDataFilter::GetComponentsType(3, fieldArray));
630 newNormals->SetNumberOfComponents(3);
631 newNormals->SetNumberOfTuples(num);
632
633 for (i = 0; i < 3; i++)
634 {
635 if (vtkFieldDataToAttributeDataFilter::ConstructArray(newNormals, i, fieldArray[i],
636 arrayComp[i], componentRange[i][0], componentRange[i][1], normalize[i]) == 0)
637 {
638 newNormals->Delete();
639 return;
640 }
641 }
642 }
643
644 attr->SetNormals(newNormals);
645 newNormals->Delete();
646 if (updated) // reset for next execution pass
647 {
648 for (i = 0; i < 3; i++)
649 {
650 componentRange[i][0] = componentRange[i][1] = -1;
651 }
652 }
653 }
654
655 // Stuff related to texture coords --------------------------------------------
656 //
SetTCoordComponent(int comp,const char * arrayName,int arrayComp,int min,int max,int normalize)657 void vtkFieldDataToAttributeDataFilter::SetTCoordComponent(
658 int comp, const char* arrayName, int arrayComp, int min, int max, int normalize)
659 {
660 if (comp < 0 || comp > 2)
661 {
662 vtkErrorMacro(<< "TCoord component must be between (0,2)");
663 return;
664 }
665
666 if (comp >= this->NumberOfTCoordComponents)
667 {
668 this->NumberOfTCoordComponents = comp + 1;
669 }
670 vtkFieldDataToAttributeDataFilter::SetArrayName(this, this->TCoordArrays[comp], arrayName);
671 if (this->TCoordArrayComponents[comp] != arrayComp)
672 {
673 this->TCoordArrayComponents[comp] = arrayComp;
674 this->Modified();
675 }
676 if (this->TCoordComponentRange[comp][0] != min)
677 {
678 this->TCoordComponentRange[comp][0] = min;
679 this->Modified();
680 }
681 if (this->TCoordComponentRange[comp][1] != max)
682 {
683 this->TCoordComponentRange[comp][1] = max;
684 this->Modified();
685 }
686 if (this->TCoordNormalize[comp] != normalize)
687 {
688 this->TCoordNormalize[comp] = normalize;
689 this->Modified();
690 }
691 }
692
GetTCoordComponentArrayName(int comp)693 const char* vtkFieldDataToAttributeDataFilter::GetTCoordComponentArrayName(int comp)
694 {
695 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
696 return this->TCoordArrays[comp];
697 }
698
GetTCoordComponentArrayComponent(int comp)699 int vtkFieldDataToAttributeDataFilter::GetTCoordComponentArrayComponent(int comp)
700 {
701 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
702 return this->TCoordArrayComponents[comp];
703 }
704
GetTCoordComponentMinRange(int comp)705 int vtkFieldDataToAttributeDataFilter::GetTCoordComponentMinRange(int comp)
706 {
707 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
708 return this->TCoordComponentRange[comp][0];
709 }
710
GetTCoordComponentMaxRange(int comp)711 int vtkFieldDataToAttributeDataFilter::GetTCoordComponentMaxRange(int comp)
712 {
713 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
714 return this->TCoordComponentRange[comp][1];
715 }
716
GetTCoordComponentNormalizeFlag(int comp)717 int vtkFieldDataToAttributeDataFilter::GetTCoordComponentNormalizeFlag(int comp)
718 {
719 comp = (comp < 0 ? 0 : (comp > 2 ? 2 : comp));
720 return this->TCoordNormalize[comp];
721 }
722
ConstructTCoords(int num,vtkFieldData * fd,vtkDataSetAttributes * attr,vtkIdType componentRange[3][2],char * arrays[3],int arrayComp[3],int normalize[3],int numComp)723 void vtkFieldDataToAttributeDataFilter::ConstructTCoords(int num, vtkFieldData* fd,
724 vtkDataSetAttributes* attr, vtkIdType componentRange[3][2], char* arrays[3], int arrayComp[3],
725 int normalize[3], int numComp)
726 {
727 int i, normalizeAny, updated = 0;
728 vtkDataArray* fieldArray[3];
729
730 if (numComp < 1)
731 {
732 return;
733 }
734 for (i = 0; i < numComp; i++)
735 {
736 if (arrays[i] == nullptr)
737 {
738 return;
739 }
740 }
741
742 for (normalizeAny = i = 0; i < numComp; i++)
743 {
744 fieldArray[i] = vtkFieldDataToAttributeDataFilter::GetFieldArray(fd, arrays[i], arrayComp[i]);
745
746 if (fieldArray[i] == nullptr)
747 {
748 vtkErrorMacro(<< "Can't find array/component requested");
749 return;
750 }
751 normalizeAny |= normalize[i];
752 }
753
754 for (i = 0; i < numComp; i++)
755 {
756 updated |=
757 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[i], componentRange[i]);
758 if (num != (componentRange[i][1] - componentRange[i][0] + 1))
759 {
760 vtkErrorMacro(<< "Number of texture coords not consistent");
761 return;
762 }
763 }
764
765 vtkDataArray* newTCoords;
766 for (i = 1; i < numComp; i++) // see whether all the data is from the same array
767 {
768 if (fieldArray[i] != fieldArray[i - 1])
769 {
770 break;
771 }
772 }
773
774 // see whether we can reuse the data array from the field
775 if (i >= numComp && fieldArray[0]->GetNumberOfComponents() == numComp &&
776 fieldArray[0]->GetNumberOfTuples() == num && !normalizeAny)
777 {
778 newTCoords = fieldArray[0];
779 newTCoords->Register(nullptr);
780 }
781 else // have to copy data into created array
782 {
783 newTCoords = vtkDataArray::CreateDataArray(
784 vtkFieldDataToAttributeDataFilter::GetComponentsType(numComp, fieldArray));
785 newTCoords->SetNumberOfComponents(numComp);
786 newTCoords->SetNumberOfTuples(num);
787
788 for (i = 0; i < numComp; i++)
789 {
790 if (vtkFieldDataToAttributeDataFilter::ConstructArray(newTCoords, i, fieldArray[i],
791 arrayComp[i], componentRange[i][0], componentRange[i][1], normalize[i]) == 0)
792 {
793 newTCoords->Delete();
794 return;
795 }
796 }
797 }
798
799 attr->SetTCoords(newTCoords);
800 newTCoords->Delete();
801 if (updated) // reset for next execution pass
802 {
803 for (i = 0; i < numComp; i++)
804 {
805 componentRange[i][0] = componentRange[i][1] = -1;
806 }
807 }
808 }
809
810 // Stuff related to tensors --------------------------------------------
811 //
SetTensorComponent(int comp,const char * arrayName,int arrayComp,int min,int max,int normalize)812 void vtkFieldDataToAttributeDataFilter::SetTensorComponent(
813 int comp, const char* arrayName, int arrayComp, int min, int max, int normalize)
814 {
815 if (comp < 0 || comp > 8)
816 {
817 vtkErrorMacro(<< "Tensor component must be between (0,8)");
818 return;
819 }
820
821 vtkFieldDataToAttributeDataFilter::SetArrayName(this, this->TensorArrays[comp], arrayName);
822 if (this->TensorArrayComponents[comp] != arrayComp)
823 {
824 this->TensorArrayComponents[comp] = arrayComp;
825 this->Modified();
826 }
827 if (this->TensorComponentRange[comp][0] != min)
828 {
829 this->TensorComponentRange[comp][0] = min;
830 this->Modified();
831 }
832 if (this->TensorComponentRange[comp][1] != max)
833 {
834 this->TensorComponentRange[comp][1] = max;
835 this->Modified();
836 }
837 if (this->TensorNormalize[comp] != normalize)
838 {
839 this->TensorNormalize[comp] = normalize;
840 this->Modified();
841 }
842 }
843
GetTensorComponentArrayName(int comp)844 const char* vtkFieldDataToAttributeDataFilter::GetTensorComponentArrayName(int comp)
845 {
846 comp = (comp < 0 ? 0 : (comp > 8 ? 8 : comp));
847 return this->TensorArrays[comp];
848 }
849
GetTensorComponentArrayComponent(int comp)850 int vtkFieldDataToAttributeDataFilter::GetTensorComponentArrayComponent(int comp)
851 {
852 comp = (comp < 0 ? 0 : (comp > 8 ? 8 : comp));
853 return this->TensorArrayComponents[comp];
854 }
855
GetTensorComponentMinRange(int comp)856 int vtkFieldDataToAttributeDataFilter::GetTensorComponentMinRange(int comp)
857 {
858 comp = (comp < 0 ? 0 : (comp > 8 ? 8 : comp));
859 return this->TensorComponentRange[comp][0];
860 }
861
GetTensorComponentMaxRange(int comp)862 int vtkFieldDataToAttributeDataFilter::GetTensorComponentMaxRange(int comp)
863 {
864 comp = (comp < 0 ? 0 : (comp > 8 ? 8 : comp));
865 return this->TensorComponentRange[comp][1];
866 }
867
GetTensorComponentNormalizeFlag(int comp)868 int vtkFieldDataToAttributeDataFilter::GetTensorComponentNormalizeFlag(int comp)
869 {
870 comp = (comp < 0 ? 0 : (comp > 8 ? 8 : comp));
871 return this->TensorNormalize[comp];
872 }
873
ConstructTensors(int num,vtkFieldData * fd,vtkDataSetAttributes * attr,vtkIdType componentRange[9][2],char * arrays[9],int arrayComp[9],int normalize[9])874 void vtkFieldDataToAttributeDataFilter::ConstructTensors(int num, vtkFieldData* fd,
875 vtkDataSetAttributes* attr, vtkIdType componentRange[9][2], char* arrays[9], int arrayComp[9],
876 int normalize[9])
877 {
878 int i, normalizeAny, updated = 0;
879 int numComp = 9;
880 vtkDataArray* fieldArray[9];
881
882 // Check for symmetric tensor input
883 if (arrayComp[6] == -1 || arrays[6] == nullptr)
884 {
885 numComp = 6;
886 }
887
888 for (i = 0; i < numComp; i++)
889 {
890 if (arrays[i] == nullptr)
891 {
892 return;
893 }
894 }
895
896 for (i = 0; i < numComp; i++)
897 {
898 fieldArray[i] = vtkFieldDataToAttributeDataFilter::GetFieldArray(fd, arrays[i], arrayComp[i]);
899
900 if (fieldArray[i] == nullptr)
901 {
902 vtkErrorMacro(<< "Can't find array requested");
903 return;
904 }
905 }
906
907 for (normalizeAny = i = 0; i < numComp; i++)
908 {
909 updated |=
910 vtkFieldDataToAttributeDataFilter::UpdateComponentRange(fieldArray[i], componentRange[i]);
911 if (num != (componentRange[i][1] - componentRange[i][0] + 1))
912 {
913 vtkErrorMacro(<< "Number of tensors not consistent");
914 return;
915 }
916 normalizeAny |= normalize[i];
917 }
918
919 vtkDataArray* newTensors;
920 for (i = 1; i < numComp; i++) // see whether all the data is from the same array
921 {
922 if (fieldArray[i] != fieldArray[i - 1])
923 {
924 break;
925 }
926 }
927
928 // see whether we can reuse the data array from the field
929 if (i >= numComp && fieldArray[0]->GetNumberOfComponents() == numComp &&
930 fieldArray[0]->GetNumberOfTuples() == num && !normalizeAny)
931 {
932 newTensors = fieldArray[0];
933 newTensors->Register(nullptr);
934 }
935 else // have to copy data into created array
936 {
937 newTensors = vtkDataArray::CreateDataArray(
938 vtkFieldDataToAttributeDataFilter::GetComponentsType(numComp, fieldArray));
939 newTensors->SetNumberOfComponents(numComp);
940 newTensors->SetNumberOfTuples(num);
941
942 for (i = 0; i < numComp; i++)
943 {
944 if (vtkFieldDataToAttributeDataFilter::ConstructArray(newTensors, i, fieldArray[i],
945 arrayComp[i], componentRange[i][0], componentRange[i][1], normalize[i]) == 0)
946 {
947 newTensors->Delete();
948 return;
949 }
950 }
951 }
952
953 attr->SetTensors(newTensors);
954 newTensors->Delete();
955 if (updated) // reset for next execution pass
956 {
957 for (i = 0; i < numComp; i++)
958 {
959 componentRange[i][0] = componentRange[i][1] = -1;
960 }
961 }
962 }
963
964 // Stuff related to fields --------------------------------------------
965 //
ConstructFieldData(int vtkNotUsed (num),vtkDataSetAttributes * vtkNotUsed (attr))966 void vtkFieldDataToAttributeDataFilter::ConstructFieldData(
967 int vtkNotUsed(num), vtkDataSetAttributes* vtkNotUsed(attr))
968 {
969 }
970
971 // Stuff related to helper methods ---------------------------------------
972 //
ConstructArray(vtkDataArray * da,int comp,vtkDataArray * fieldArray,int fieldComp,vtkIdType min,vtkIdType max,int normalize)973 int vtkFieldDataToAttributeDataFilter::ConstructArray(vtkDataArray* da, int comp,
974 vtkDataArray* fieldArray, int fieldComp, vtkIdType min, vtkIdType max, int normalize)
975 {
976 vtkIdType i, n = max - min + 1;
977 float minValue = VTK_FLOAT_MAX;
978 float maxValue = -VTK_FLOAT_MAX;
979 float compRange, compValue;
980
981 if (fieldComp >= fieldArray->GetNumberOfComponents())
982 {
983 vtkGenericWarningMacro(<< "Trying to access component out of range");
984 return 0;
985 }
986
987 for (i = 0; i < n; i++)
988 {
989 compValue = fieldArray->GetComponent(min + i, fieldComp);
990 if (compValue < minValue)
991 {
992 minValue = compValue;
993 }
994 if (compValue > maxValue)
995 {
996 maxValue = compValue;
997 }
998 da->SetComponent(i, comp, compValue);
999 }
1000
1001 if (normalize)
1002 {
1003 compRange = maxValue - minValue;
1004 if (compRange != 0.0)
1005 {
1006 for (i = 0; i < n; i++)
1007 {
1008 compValue = da->GetComponent(i, comp);
1009 compValue = (compValue - minValue) / compRange;
1010 da->SetComponent(i, comp, compValue);
1011 }
1012 }
1013 }
1014
1015 return 1;
1016 }
1017
GetComponentsType(int numComp,vtkDataArray ** arrays)1018 int vtkFieldDataToAttributeDataFilter::GetComponentsType(int numComp, vtkDataArray** arrays)
1019 {
1020 int type, mostComplexType = VTK_VOID;
1021
1022 for (int i = 0; i < numComp; i++)
1023 {
1024 type = arrays[i]->GetDataType();
1025 if (type > mostComplexType)
1026 {
1027 mostComplexType = type;
1028 }
1029 }
1030
1031 return mostComplexType;
1032 }
1033
GetFieldArray(vtkFieldData * fd,const char * name,int comp)1034 vtkDataArray* vtkFieldDataToAttributeDataFilter::GetFieldArray(
1035 vtkFieldData* fd, const char* name, int comp)
1036 {
1037 vtkDataArray* da = nullptr;
1038 int numComp;
1039 bool found = false;
1040
1041 if (name != nullptr)
1042 {
1043 vtkDataSetAttributes* dsa;
1044 if ((dsa = vtkDataSetAttributes::SafeDownCast(fd)))
1045 {
1046 found = true;
1047 if (!strcmp("PointScalars", name) || !strcmp("CellScalars", name))
1048 {
1049 da = dsa->GetScalars();
1050 }
1051 else if (!strcmp("PointVectors", name) || !strcmp("CellVectors", name))
1052 {
1053 da = dsa->GetVectors();
1054 }
1055 else if (!strcmp("PointTensors", name) || !strcmp("CellTensors", name))
1056 {
1057 da = dsa->GetTensors();
1058 }
1059 else if (!strcmp("PointNormals", name) || !strcmp("CellNormals", name))
1060 {
1061 da = dsa->GetNormals();
1062 }
1063 else if (!strcmp("PointTCoords", name) || !strcmp("CellTCoords", name))
1064 {
1065 da = dsa->GetTCoords();
1066 }
1067 else
1068 {
1069 found = false;
1070 }
1071 }
1072 if (!found || !da)
1073 {
1074 da = fd->GetArray(name);
1075 }
1076
1077 if (da == nullptr)
1078 {
1079 return nullptr;
1080 }
1081 numComp = da->GetNumberOfComponents();
1082 if (comp < 0 || comp >= numComp)
1083 {
1084 return nullptr;
1085 }
1086 else
1087 {
1088 return da;
1089 }
1090 }
1091
1092 return nullptr;
1093 }
1094
SetArrayName(vtkObject * self,char * & name,const char * newName)1095 void vtkFieldDataToAttributeDataFilter::SetArrayName(
1096 vtkObject* self, char*& name, const char* newName)
1097 {
1098 if (name && newName && (!strcmp(name, newName)))
1099 {
1100 return;
1101 }
1102 delete[] name;
1103 if (newName)
1104 {
1105 name = new char[strlen(newName) + 1];
1106 strcpy(name, newName);
1107 }
1108 else
1109 {
1110 name = nullptr;
1111 }
1112 self->Modified();
1113 }
1114
UpdateComponentRange(vtkDataArray * da,vtkIdType compRange[2])1115 int vtkFieldDataToAttributeDataFilter::UpdateComponentRange(
1116 vtkDataArray* da, vtkIdType compRange[2])
1117 {
1118 if (compRange[0] == -1)
1119 {
1120 compRange[0] = 0;
1121 compRange[1] = da->GetNumberOfTuples() - 1;
1122 return 1;
1123 }
1124 else
1125 {
1126 return 0;
1127 }
1128 }
1129
1130 //------------------------------------------------------------------------------
RequestUpdateExtent(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)1131 int vtkFieldDataToAttributeDataFilter::RequestUpdateExtent(vtkInformation* vtkNotUsed(request),
1132 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
1133 {
1134 // get the info objects
1135 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
1136 vtkInformation* outInfo = outputVector->GetInformationObject(0);
1137
1138 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
1139 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
1140 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
1141 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
1142 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
1143 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
1144 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
1145 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT()), 6);
1146 inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(),
1147 outInfo->Get(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT()));
1148 return 1;
1149 }
1150