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