1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkInterpolateDataSetAttributes.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 "vtkInterpolateDataSetAttributes.h"
16 
17 #include "vtkCellData.h"
18 #include "vtkDataSetCollection.h"
19 #include "vtkExecutive.h"
20 #include "vtkGarbageCollector.h"
21 #include "vtkInformation.h"
22 #include "vtkInformationVector.h"
23 #include "vtkObjectFactory.h"
24 #include "vtkPointData.h"
25 #include "vtkPolyData.h"
26 #include "vtkRectilinearGrid.h"
27 #include "vtkStructuredGrid.h"
28 #include "vtkStructuredPoints.h"
29 #include "vtkUnstructuredGrid.h"
30 
31 vtkStandardNewMacro(vtkInterpolateDataSetAttributes);
32 
33 // Create object with no input or output.
vtkInterpolateDataSetAttributes()34 vtkInterpolateDataSetAttributes::vtkInterpolateDataSetAttributes()
35 {
36   this->InputList = vtkDataSetCollection::New();
37 
38   this->T = 0.0;
39 }
40 
~vtkInterpolateDataSetAttributes()41 vtkInterpolateDataSetAttributes::~vtkInterpolateDataSetAttributes()
42 {
43   if (this->InputList)
44   {
45     this->InputList->Delete();
46     this->InputList = nullptr;
47   }
48 }
49 
GetInputList()50 vtkDataSetCollection* vtkInterpolateDataSetAttributes::GetInputList()
51 {
52   int i;
53   this->InputList->RemoveAllItems();
54 
55   for (i = 0; i < this->GetNumberOfInputConnections(0); i++)
56   {
57     this->InputList->AddItem(static_cast<vtkDataSet*>(this->GetExecutive()->GetInputData(0, i)));
58   }
59   return this->InputList;
60 }
61 
62 // Interpolate the data
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)63 int vtkInterpolateDataSetAttributes::RequestData(vtkInformation* vtkNotUsed(request),
64   vtkInformationVector** inputVector, vtkInformationVector* outputVector)
65 {
66   // get the info object
67   vtkInformation* outInfo = outputVector->GetInformationObject(0);
68 
69   // get the output
70   vtkDataSet* output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
71 
72   vtkIdType numPts, numCells, i;
73   int numInputs = this->GetNumberOfInputConnections(0);
74   int lowDS, highDS;
75   vtkDataSet *ds, *ds2;
76   vtkPointData* outputPD = output->GetPointData();
77   vtkCellData* outputCD = output->GetCellData();
78   vtkPointData *inputPD, *input2PD;
79   vtkCellData *inputCD, *input2CD;
80   double t;
81 
82   if (numInputs < 2)
83   {
84     vtkErrorMacro(<< "Need at least two inputs to interpolate!");
85     return 1;
86   }
87 
88   vtkDebugMacro(<< "Interpolating data...");
89 
90   // Check input and determine between which data sets the interpolation
91   // is to occur.
92   if (this->T > static_cast<double>(numInputs))
93   {
94     vtkErrorMacro(<< "Bad interpolation parameter");
95     return 1;
96   }
97 
98   lowDS = static_cast<int>(this->T);
99   if (lowDS >= (numInputs - 1))
100   {
101     lowDS = numInputs - 2;
102   }
103 
104   highDS = lowDS + 1;
105   t = this->T - static_cast<double>(lowDS);
106   if (t > 1.0)
107   {
108     t = 1.0;
109   }
110 
111   vtkInformation* dsInfo = inputVector[0]->GetInformationObject(lowDS);
112   vtkInformation* ds2Info = inputVector[0]->GetInformationObject(highDS);
113   ds = vtkDataSet::SafeDownCast(dsInfo->Get(vtkDataObject::DATA_OBJECT()));
114   ds2 = vtkDataSet::SafeDownCast(ds2Info->Get(vtkDataObject::DATA_OBJECT()));
115 
116   numPts = ds->GetNumberOfPoints();
117   numCells = ds->GetNumberOfCells();
118 
119   if (numPts != ds2->GetNumberOfPoints() || numCells != ds2->GetNumberOfCells())
120   {
121     vtkErrorMacro(<< "Data sets not consistent!");
122     return 1;
123   }
124 
125   output->CopyStructure(ds);
126   inputPD = ds->GetPointData();
127   inputCD = ds->GetCellData();
128   input2PD = ds2->GetPointData();
129   input2CD = ds2->GetCellData();
130 
131   // Allocate the data set attributes
132   outputPD->CopyAllOff();
133   if (inputPD->GetScalars() && input2PD->GetScalars())
134   {
135     outputPD->CopyScalarsOn();
136   }
137   if (inputPD->GetVectors() && input2PD->GetVectors())
138   {
139     outputPD->CopyVectorsOn();
140   }
141   if (inputPD->GetNormals() && input2PD->GetNormals())
142   {
143     outputPD->CopyNormalsOn();
144   }
145   if (inputPD->GetTCoords() && input2PD->GetTCoords())
146   {
147     outputPD->CopyTCoordsOn();
148   }
149   if (inputPD->GetTensors() && input2PD->GetTensors())
150   {
151     outputPD->CopyTensorsOn();
152   }
153   // *TODO* Fix
154   // if ( inputPD->GetFieldData() && input2PD->GetFieldData() )
155   //{
156   // outputPD->CopyFieldDataOn();
157   //}
158   outputPD->InterpolateAllocate(inputPD);
159 
160   outputCD->CopyAllOff();
161   if (inputCD->GetScalars() && input2CD->GetScalars())
162   {
163     outputCD->CopyScalarsOn();
164   }
165   if (inputCD->GetVectors() && input2CD->GetVectors())
166   {
167     outputCD->CopyVectorsOn();
168   }
169   if (inputCD->GetNormals() && input2CD->GetNormals())
170   {
171     outputCD->CopyNormalsOn();
172   }
173   if (inputCD->GetTCoords() && input2CD->GetTCoords())
174   {
175     outputCD->CopyTCoordsOn();
176   }
177   if (inputCD->GetTensors() && input2CD->GetTensors())
178   {
179     outputCD->CopyTensorsOn();
180   }
181   // *TODO* Fix
182   // if ( inputCD->GetFieldData() && input2CD->GetFieldData() )
183   //{
184   // outputCD->CopyFieldDataOn();
185   //  }
186   outputCD->InterpolateAllocate(inputCD);
187 
188   // Interpolate point data. We'll assume that it takes 50% of the time
189   for (i = 0; i < numPts; i++)
190   {
191     if (!(i % 10000))
192     {
193       this->UpdateProgress(static_cast<double>(i) / numPts * 0.50);
194       if (this->GetAbortExecute())
195       {
196         break;
197       }
198     }
199 
200     outputPD->InterpolateTime(inputPD, input2PD, i, t);
201   }
202 
203   // Interpolate cell data. We'll assume that it takes 50% of the time
204   for (i = 0; i < numCells; i++)
205   {
206     if (!(i % 10000))
207     {
208       this->UpdateProgress(0.5 + static_cast<double>(i) / numCells * 0.50);
209       if (this->GetAbortExecute())
210       {
211         break;
212       }
213     }
214 
215     outputCD->InterpolateTime(inputCD, input2CD, i, t);
216   }
217 
218   return 1;
219 }
220 
FillInputPortInformation(int port,vtkInformation * info)221 int vtkInterpolateDataSetAttributes::FillInputPortInformation(int port, vtkInformation* info)
222 {
223   if (!this->Superclass::FillInputPortInformation(port, info))
224   {
225     return 0;
226   }
227   info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
228   return 1;
229 }
230 
PrintSelf(ostream & os,vtkIndent indent)231 void vtkInterpolateDataSetAttributes::PrintSelf(ostream& os, vtkIndent indent)
232 {
233   this->Superclass::PrintSelf(os, indent);
234 
235   os << indent << "T: " << this->T << endl;
236 }
237 
238 //------------------------------------------------------------------------------
ReportReferences(vtkGarbageCollector * collector)239 void vtkInterpolateDataSetAttributes ::ReportReferences(vtkGarbageCollector* collector)
240 {
241   this->Superclass::ReportReferences(collector);
242   vtkGarbageCollectorReport(collector, this->InputList, "InputList");
243 }
244