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