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