1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkTupleInterpolator.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 "vtkTupleInterpolator.h"
16 #include "vtkKochanekSpline.h"
17 #include "vtkMath.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkPiecewiseFunction.h"
20 #include "vtkSpline.h"
21 
22 vtkStandardNewMacro(vtkTupleInterpolator);
23 
24 //------------------------------------------------------------------------------
vtkTupleInterpolator()25 vtkTupleInterpolator::vtkTupleInterpolator()
26 {
27   // Set up the interpolation
28   this->NumberOfComponents = 0;
29   this->InterpolationType = INTERPOLATION_TYPE_SPLINE;
30   this->InterpolatingSpline = nullptr;
31 
32   this->Spline = nullptr;
33   this->Linear = nullptr;
34 }
35 
36 //------------------------------------------------------------------------------
~vtkTupleInterpolator()37 vtkTupleInterpolator::~vtkTupleInterpolator()
38 {
39   this->Initialize();
40   if (this->InterpolatingSpline)
41   {
42     this->InterpolatingSpline->Delete();
43   }
44 }
45 
46 //------------------------------------------------------------------------------
SetNumberOfComponents(int numComp)47 void vtkTupleInterpolator::SetNumberOfComponents(int numComp)
48 {
49   numComp = (numComp < 1 ? 1 : numComp);
50   if (numComp != this->NumberOfComponents)
51   {
52     this->Initialize(); // wipe out data
53     this->NumberOfComponents = numComp;
54     this->InitializeInterpolation();
55     this->Modified();
56   }
57 }
58 
59 //------------------------------------------------------------------------------
GetNumberOfTuples()60 int vtkTupleInterpolator::GetNumberOfTuples()
61 {
62   if (this->Spline)
63   {
64     return this->Spline[0]->GetNumberOfPoints();
65   }
66   else if (this->Linear)
67   {
68     return this->Linear[0]->GetSize();
69   }
70   else
71   {
72     return 0;
73   }
74 }
75 
76 //------------------------------------------------------------------------------
GetMinimumT()77 double vtkTupleInterpolator::GetMinimumT()
78 {
79   if (this->Spline)
80   {
81     double range[2];
82     this->Spline[0]->GetParametricRange(range);
83     return range[0];
84   }
85   else if (this->Linear)
86   {
87     return this->Linear[0]->GetRange()[0];
88   }
89   else
90   {
91     return 0.0;
92   }
93 }
94 
95 //------------------------------------------------------------------------------
GetMaximumT()96 double vtkTupleInterpolator::GetMaximumT()
97 {
98   if (this->Spline)
99   {
100     double range[2];
101     this->Spline[0]->GetParametricRange(range);
102     return range[1];
103   }
104   else if (this->Linear)
105   {
106     return this->Linear[0]->GetRange()[1];
107   }
108   else
109   {
110     return 1.0;
111   }
112 }
113 
114 //------------------------------------------------------------------------------
Initialize()115 void vtkTupleInterpolator::Initialize()
116 {
117   int i;
118 
119   // Wipe out old data
120   if (this->Spline)
121   {
122     for (i = 0; i < this->NumberOfComponents; i++)
123     {
124       this->Spline[i]->Delete();
125     }
126     delete[] this->Spline;
127     this->Spline = nullptr;
128   }
129   if (this->Linear)
130   {
131     for (i = 0; i < this->NumberOfComponents; i++)
132     {
133       this->Linear[i]->Delete();
134     }
135     delete[] this->Linear;
136     this->Linear = nullptr;
137   }
138 
139   this->NumberOfComponents = 0;
140 }
141 
142 //------------------------------------------------------------------------------
InitializeInterpolation()143 void vtkTupleInterpolator::InitializeInterpolation()
144 {
145   // Prepare for new data
146   if (this->NumberOfComponents <= 0)
147   {
148     return;
149   }
150 
151   int i;
152   if (this->InterpolationType == INTERPOLATION_TYPE_LINEAR)
153   {
154     this->Linear = new vtkPiecewiseFunction*[this->NumberOfComponents];
155     for (i = 0; i < this->NumberOfComponents; i++)
156     {
157       this->Linear[i] = vtkPiecewiseFunction::New();
158     }
159   }
160 
161   else // this->InterpolationType == INTERPOLATION_TYPE_SPLINE
162   {
163     this->Spline = new vtkSpline*[this->NumberOfComponents];
164     if (!this->InterpolatingSpline)
165     {
166       this->InterpolatingSpline = vtkKochanekSpline::New();
167     }
168     for (i = 0; i < this->NumberOfComponents; i++)
169     {
170       this->Spline[i] = this->InterpolatingSpline->NewInstance();
171       this->Spline[i]->DeepCopy(this->InterpolatingSpline);
172       this->Spline[i]->RemoveAllPoints();
173     }
174   }
175 }
176 
177 //------------------------------------------------------------------------------
SetInterpolationType(int type)178 void vtkTupleInterpolator::SetInterpolationType(int type)
179 {
180   type = (type < INTERPOLATION_TYPE_LINEAR
181       ? INTERPOLATION_TYPE_LINEAR
182       : (type > INTERPOLATION_TYPE_SPLINE ? INTERPOLATION_TYPE_SPLINE : type));
183   if (type != this->InterpolationType)
184   {
185     this->Initialize(); // wipe out data
186     this->InterpolationType = type;
187     this->InitializeInterpolation();
188     this->Modified();
189   }
190 }
191 
192 //------------------------------------------------------------------------------
SetInterpolatingSpline(vtkSpline * spline)193 void vtkTupleInterpolator::SetInterpolatingSpline(vtkSpline* spline)
194 {
195   if (this->InterpolatingSpline == spline)
196   {
197     return;
198   }
199   if (this->InterpolatingSpline)
200   {
201     this->InterpolatingSpline->UnRegister(this);
202     this->InterpolatingSpline = nullptr;
203   }
204   if (spline)
205   {
206     spline->Register(this);
207   }
208   this->InterpolatingSpline = spline;
209   this->Modified();
210 }
211 
212 //------------------------------------------------------------------------------
AddTuple(double t,double tuple[])213 void vtkTupleInterpolator::AddTuple(double t, double tuple[])
214 {
215   int i;
216   if (this->InterpolationType == INTERPOLATION_TYPE_LINEAR)
217   {
218     for (i = 0; i < this->NumberOfComponents; i++)
219     {
220       this->Linear[i]->AddPoint(t, tuple[i]);
221     }
222   }
223 
224   else // this->InterpolationType == INTERPOLATION_TYPE_SPLINE
225   {
226     for (i = 0; i < this->NumberOfComponents; i++)
227     {
228       this->Spline[i]->AddPoint(t, tuple[i]);
229     }
230   }
231 
232   this->Modified();
233 }
234 
235 //------------------------------------------------------------------------------
RemoveTuple(double t)236 void vtkTupleInterpolator::RemoveTuple(double t)
237 {
238   int i;
239   if (this->InterpolationType == INTERPOLATION_TYPE_LINEAR)
240   {
241     for (i = 0; i < this->NumberOfComponents; i++)
242     {
243       this->Linear[i]->RemovePoint(t);
244     }
245   }
246 
247   else // this->InterpolationType == INTERPOLATION_TYPE_SPLINE
248   {
249     for (i = 0; i < this->NumberOfComponents; i++)
250     {
251       this->Spline[i]->RemovePoint(t);
252     }
253   }
254 
255   this->Modified();
256 }
257 
258 //------------------------------------------------------------------------------
InterpolateTuple(double t,double tuple[])259 void vtkTupleInterpolator::InterpolateTuple(double t, double tuple[])
260 {
261   if (this->NumberOfComponents <= 0)
262   {
263     return;
264   }
265 
266   int i;
267   if (this->InterpolationType == INTERPOLATION_TYPE_LINEAR)
268   {
269     double* range = this->Linear[0]->GetRange();
270     t = (t < range[0] ? range[0] : (t > range[1] ? range[1] : t));
271     for (i = 0; i < this->NumberOfComponents; i++)
272     {
273       tuple[i] = this->Linear[i]->GetValue(t);
274     }
275   }
276 
277   else // this->InterpolationType == INTERPOLATION_TYPE_SPLINE
278   {
279     for (i = 0; i < this->NumberOfComponents; i++)
280     {
281       tuple[i] = this->Spline[i]->Evaluate(t);
282     }
283   }
284 }
285 
286 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)287 void vtkTupleInterpolator::PrintSelf(ostream& os, vtkIndent indent)
288 {
289   this->Superclass::PrintSelf(os, indent);
290 
291   os << indent << "There are " << this->GetNumberOfTuples() << " tuples to be interpolated\n";
292 
293   os << indent << "Number of Components: " << this->NumberOfComponents << "\n";
294 
295   os << indent << "Interpolation Type: "
296      << (this->InterpolationType == INTERPOLATION_TYPE_LINEAR ? "Linear\n" : "Spline\n");
297 
298   os << indent << "Interpolating Spline: ";
299   if (this->InterpolatingSpline)
300   {
301     os << this->InterpolatingSpline << "\n";
302   }
303   else
304   {
305     os << "(null)\n";
306   }
307 }
308