1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkStreamer.h
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 // .NAME vtkStreamer - abstract object implements integration of massless particle through vector field
16 // .SECTION Description
17 // vtkStreamer is a filter that integrates a massless particle through a vector
18 // field. The integration is performed using second order Runge-Kutta method.
19 // vtkStreamer often serves as a base class for other classes that perform
20 // numerical integration through a vector field (e.g., vtkStreamLine).
21 //
22 // Note that vtkStreamer can integrate both forward and backward in time,
23 // or in both directions. The length of the streamer is controlled by
24 // specifying an elapsed time. (The elapsed time is the time each particle
25 // travels.) Otherwise, the integration terminates after exiting the dataset or
26 // if the particle speed is reduced to a value less than the terminal speed.
27 //
28 // vtkStreamer integrates through any type of dataset. As a result, if the
29 // dataset contains 2D cells such as polygons or triangles, the integration is
30 // constrained to lie on the surface defined by the 2D cells.
31 //
32 // The starting point of streamers may be defined in three different ways.
33 // Starting from global x-y-z "position" allows you to start a single streamer
34 // at a specified x-y-z coordinate. Starting from "location" allows you to
35 // start at a specified cell, subId, and parametric coordinate. Finally, you
36 // may specify a source object to start multiple streamers. If you start
37 // streamers using a source object, for each point in the source that is
38 // inside the dataset a streamer is created.
39 //
40 // vtkStreamer implements the integration process in the Integrate() method.
41 // Because vtkStreamer does not implement the Execute() method that its
42 // superclass (i.e., Filter) requires, it is an abstract class. Its subclasses
43 // implement the execute method and use the Integrate() method, and then build
44 // their own representation of the integration path (i.e., lines, dashed
45 // lines, points, etc.).
46
47 // .SECTION See Also
48 // vtkStreamLine vtkDashedStreamLine vtkStreamPoints
49
50 #ifndef vtkStreamer_h
51 #define vtkStreamer_h
52
53 #include "vtkFiltersFlowPathsModule.h" // For export macro
54 #include "vtkPolyDataAlgorithm.h"
55
56 class vtkInitialValueProblemSolver;
57 class vtkMultiThreader;
58
59 #define VTK_INTEGRATE_FORWARD 0
60 #define VTK_INTEGRATE_BACKWARD 1
61 #define VTK_INTEGRATE_BOTH_DIRECTIONS 2
62
63 class VTKFILTERSFLOWPATHS_EXPORT vtkStreamer : public vtkPolyDataAlgorithm
64 {
65 public:
66 vtkTypeMacro(vtkStreamer,vtkPolyDataAlgorithm);
67 void PrintSelf(ostream& os, vtkIndent indent);
68
69 // Description:
70 // Specify the start of the streamline in the cell coordinate system. That
71 // is, cellId and subId (if composite cell), and parametric coordinates.
72 void SetStartLocation(vtkIdType cellId, int subId, double pcoords[3]);
73
74 // Description:
75 // Specify the start of the streamline in the cell coordinate system. That
76 // is, cellId and subId (if composite cell), and parametric coordinates.
77 void SetStartLocation(vtkIdType cellId, int subId, double r, double s,
78 double t);
79
80 // Description:
81 // Get the starting location of the streamline in the cell coordinate system.
82 vtkIdType GetStartLocation(int& subId, double pcoords[3]);
83
84 // Description:
85 // Specify the start of the streamline in the global coordinate
86 // system. Search must be performed to find initial cell to start
87 // integration from.
88 void SetStartPosition(double x[3]);
89
90 // Description:
91 // Specify the start of the streamline in the global coordinate
92 // system. Search must be performed to find initial cell to start
93 // integration from.
94 void SetStartPosition(double x, double y, double z);
95
96 // Description:
97 // Get the start position in global x-y-z coordinates.
98 double *GetStartPosition();
99
100 // Description:
101 // Specify the source object used to generate starting points.
102 void SetSourceData(vtkDataSet *source);
103 vtkDataSet *GetSource();
104
105 //Description:
106 // Specify the source object used to generate starting points
107 // by making a pipeline connection
108 void SetSourceConnection(vtkAlgorithmOutput* algOutput);
109
110 // Description:
111 // Specify the maximum length of the Streamer expressed in elapsed time.
112 vtkSetClampMacro(MaximumPropagationTime,double,0.0,VTK_DOUBLE_MAX);
113 vtkGetMacro(MaximumPropagationTime,double);
114
115 // Description:
116 // Specify the direction in which to integrate the Streamer.
117 vtkSetClampMacro(IntegrationDirection,int,
118 VTK_INTEGRATE_FORWARD,VTK_INTEGRATE_BOTH_DIRECTIONS);
119 vtkGetMacro(IntegrationDirection,int);
SetIntegrationDirectionToForward()120 void SetIntegrationDirectionToForward()
121 {this->SetIntegrationDirection(VTK_INTEGRATE_FORWARD);};
SetIntegrationDirectionToBackward()122 void SetIntegrationDirectionToBackward()
123 {this->SetIntegrationDirection(VTK_INTEGRATE_BACKWARD);};
SetIntegrationDirectionToIntegrateBothDirections()124 void SetIntegrationDirectionToIntegrateBothDirections()
125 {this->SetIntegrationDirection(VTK_INTEGRATE_BOTH_DIRECTIONS);};
126 const char *GetIntegrationDirectionAsString();
127
128 // Description:
129 // Specify a nominal integration step size (expressed as a fraction of
130 // the size of each cell). This value can be larger than 1.
131 vtkSetClampMacro(IntegrationStepLength,double,0.0000001,VTK_DOUBLE_MAX);
132 vtkGetMacro(IntegrationStepLength,double);
133
134 // Description:
135 // Turn on/off the creation of scalar data from velocity magnitude. If off,
136 // and input dataset has scalars, input dataset scalars are used.
137 vtkSetMacro(SpeedScalars,int);
138 vtkGetMacro(SpeedScalars,int);
139 vtkBooleanMacro(SpeedScalars,int);
140
141 // Description:
142 // Turn on/off the creation of scalar data from vorticity information.
143 // The scalar information is currently the orientation value "theta"
144 // used in rotating stream tubes. If off, and input dataset has scalars,
145 // then input dataset scalars are used, unless SpeedScalars is also on.
146 // SpeedScalars takes precedence over OrientationScalars.
147 vtkSetMacro(OrientationScalars, int);
148 vtkGetMacro(OrientationScalars, int);
149 vtkBooleanMacro(OrientationScalars, int);
150
151 // Description:
152 // Set/get terminal speed (i.e., speed is velocity magnitude). Terminal
153 // speed is speed at which streamer will terminate propagation.
154 vtkSetClampMacro(TerminalSpeed,double,0.0,VTK_DOUBLE_MAX);
155 vtkGetMacro(TerminalSpeed,double);
156
157 // Description:
158 // Turn on/off the computation of vorticity. Vorticity is an indication of
159 // the rotation of the flow. In combination with vtkStreamLine and
160 // vtkTubeFilter can be used to create rotated tubes.
161 // If vorticity is turned on, in the output, the velocity vectors
162 // are replaced by vorticity vectors.
163 vtkSetMacro(Vorticity,int);
164 vtkGetMacro(Vorticity,int);
165 vtkBooleanMacro(Vorticity,int);
166
167 vtkSetMacro( NumberOfThreads, int );
168 vtkGetMacro( NumberOfThreads, int );
169
170 vtkSetMacro( SavePointInterval, double );
171 vtkGetMacro( SavePointInterval, double );
172
173 // Description:
174 // Set/get the integrator type to be used in the stream line
175 // calculation. The object passed is not actually used but
176 // is cloned with NewInstance by each thread/process in the
177 // process of integration (prototype pattern). The default is
178 // 2nd order Runge Kutta.
179 void SetIntegrator(vtkInitialValueProblemSolver *);
180 vtkGetObjectMacro ( Integrator, vtkInitialValueProblemSolver );
181
182 // Description:
183 // A positive value, as small as possible for numerical comparison.
184 // The initial value is 1E-12.
185 vtkSetMacro(Epsilon,double);
186 vtkGetMacro(Epsilon,double);
187
188 protected:
189 // Description:
190 // Construct object to start from position (0,0,0); integrate forward;
191 // terminal speed 0.0; vorticity computation off; integrations step length
192 // 0.2; and maximum propagation time 100.0.
193 vtkStreamer();
194 ~vtkStreamer();
195
196 // Integrate data
197 void Integrate(vtkDataSet *input, vtkDataSet *source);
198
199 // Controls where streamlines start from (either position or location).
200 int StartFrom;
201
202 // Starting from cell location
203 vtkIdType StartCell;
204 int StartSubId;
205 double StartPCoords[3];
206
207 // starting from global x-y-z position
208 double StartPosition[3];
209
210 //
211 // Special classes for manipulating data
212 //
213 //BTX - begin tcl exclude
214 //
215 class StreamPoint {
216 public:
217 double x[3]; // position
218 vtkIdType cellId; // cell
219 int subId; // cell sub id
220 double p[3]; // parametric coords in cell
221 double v[3]; // velocity
222 double speed; // velocity norm
223 double s; // scalar value
224 double t; // time travelled so far
225 double d; // distance travelled so far
226 double omega; // stream vorticity, if computed
227 double theta; // rotation angle, if vorticity is computed
228 };
229
230 class StreamArray;
231 friend class StreamArray;
232 class StreamArray { //;prevent man page generation
233 public:
234 StreamArray();
~StreamArray()235 ~StreamArray()
236 {
237 delete [] this->Array;
238 };
GetNumberOfPoints()239 vtkIdType GetNumberOfPoints() {return this->MaxId + 1;};
GetStreamPoint(vtkIdType i)240 StreamPoint *GetStreamPoint(vtkIdType i) {return this->Array + i;};
InsertNextStreamPoint()241 vtkIdType InsertNextStreamPoint()
242 {
243 if ( ++this->MaxId >= this->Size )
244 {
245 this->Resize(this->MaxId);
246 }
247 return this->MaxId; //return offset from array
248 }
249 StreamPoint *Resize(vtkIdType sz); //reallocates data
Reset()250 void Reset() {this->MaxId = -1;};
251
252 StreamPoint *Array; // pointer to data
253 vtkIdType MaxId; // maximum index inserted thus far
254 vtkIdType Size; // allocated size of data
255 vtkIdType Extend; // grow array by this amount
256 double Direction; // integration direction
257 };
258 //ETX
259 //
260
261 //array of streamers
262 StreamArray *Streamers;
263 vtkIdType NumberOfStreamers;
264
265 // length of Streamer is generated by time, or by MaximumSteps
266 double MaximumPropagationTime;
267
268 // integration direction
269 int IntegrationDirection;
270
271 // the length (fraction of cell size) of integration steps
272 double IntegrationStepLength;
273
274 // boolean controls whether vorticity is computed
275 int Vorticity;
276
277 // terminal propagation speed
278 double TerminalSpeed;
279
280 // boolean controls whether data scalars or velocity magnitude are used
281 int SpeedScalars;
282
283 // boolean controls whether data scalars or vorticity orientation are used
284 int OrientationScalars;
285
286 // Prototype showing the integrator type to be set by the user.
287 vtkInitialValueProblemSolver* Integrator;
288
289 // A positive value, as small as possible for numerical comparison.
290 // The initial value is 1E-12.
291 double Epsilon;
292
293 // Interval with which the stream points will be stored.
294 // Useful in reducing the memory footprint. Since the initial
295 // value is small, by default, it will store all/most points.
296 double SavePointInterval;
297
298 static VTK_THREAD_RETURN_TYPE ThreadedIntegrate( void *arg );
299
300 // Description:
301 // These methods were added to allow access to these variables from the
302 // threads.
303 vtkGetMacro( NumberOfStreamers, vtkIdType );
GetStreamers()304 StreamArray *GetStreamers() { return this->Streamers; };
305
306 void InitializeThreadedIntegrate();
307 vtkMultiThreader *Threader;
308 int NumberOfThreads;
309
310 virtual int FillInputPortInformation(int port, vtkInformation *info);
311
312 private:
313 vtkStreamer(const vtkStreamer&); // Not implemented.
314 void operator=(const vtkStreamer&); // Not implemented.
315 };
316
317 // Description:
318 // Return the integration direction as a character string.
GetIntegrationDirectionAsString()319 inline const char *vtkStreamer::GetIntegrationDirectionAsString()
320 {
321 if ( this->IntegrationDirection == VTK_INTEGRATE_FORWARD )
322 {
323 return "IntegrateForward";
324 }
325 else if ( this->IntegrationDirection == VTK_INTEGRATE_BACKWARD )
326 {
327 return "IntegrateBackward";
328 }
329 else
330 {
331 return "IntegrateBothDirections";
332 }
333 }
334
335 #endif
336