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