1 /*=========================================================================
3 Program: Visualization Toolkit
4 Module: $RCSfile: vtkStreamTracer.h,v $
6 Date: $Date: 2003/01/09 19:21:05 $
7 Version: $Revision: 1.13 $
9 Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
11 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notice for more information.
17 =========================================================================*/
18 // .NAME vtkStreamTracer - Streamline generator
19 // .SECTION Description
20 // vtkStreamTracer is a filter that integrates a vector field to generate
21 // streamlines. The integration is performed using the provided integrator.
22 // The default is second order Runge-Kutta.
24 // vtkStreamTracer generate polylines as output. Each cell (polyline)
25 // corresponds to one streamline. The values associated with each streamline
26 // are stored in the cell data whereas the values associated with points
27 // are stored in point data.
29 // Note that vtkStreamTracer can integrate both forward and backward.
30 // The length of the streamline is controlled by specifying either
31 // a maximum value in the units of length, cell length or elapsed time
32 // (the elapsed time is the time each particle would have traveled if
33 // flow were steady). Otherwise, the integration terminates after exiting
34 // the dataset or if the particle speed is reduced to a value less than
35 // the terminal speed or when a maximum number of steps is reached.
36 // The reason for the termination is stored in a cell array named
37 // ReasonForTermination.
39 // The quality of integration can be controlled by setting integration
40 // step (InitialIntegrationStep) and in the case of adaptive solvers
41 // the maximum error, the minimum integration step and the maximum
42 // integration step. All of these can have units of length, cell length
45 // The integration time, vorticity, rotation and angular velocity
46 // are stored in point arrays named "IntegrationTime", "Vorticity",
47 // "Rotation" and "AngularVelocity" respectively (vorticity, rotation
48 // and angular velocity are computed only when ComputeVorticity is on).
49 // All point attributes in the source data set are interpolated on the
50 // new streamline points.
52 // vtkStreamTracer integrates through any type of dataset. As a result, if the
53 // dataset contains 2D cells such as polygons or triangles, the integration is
54 // constrained to lie on the surface defined by the 2D cells.
56 // The starting point of traces may be defined in two different ways.
57 // Starting from global x-y-z "position" allows you to start a single trace
58 // at a specified x-y-z coordinate. If you specify a source object,
59 // a trace will be generated for each point in the source that is
60 // inside the dataset.
63 // vtkRibbonFilter vtkRuledSurfaceFilter vtkInitialValueProblemSolver
64 // vtkRungeKutta2 vtkRungeKutta4 vtkRungeKutta45
66 #ifndef __vtkStreamTracer_h
67 #define __vtkStreamTracer_h
69 #include "vtkDataSetToPolyDataFilter.h"
71 #include "vtkInitialValueProblemSolver.h" // Needed for constants
78 class vtkInterpolatedVelocityField;
80 class VTK_GRAPHICS_EXPORT vtkStreamTracer : public vtkDataSetToPolyDataFilter
83 vtkTypeRevisionMacro(vtkStreamTracer,vtkDataSetToPolyDataFilter);
84 void PrintSelf(ostream& os, vtkIndent indent);
87 // Construct object to start from position (0,0,0), integrate forward,
88 // terminal speed 1.0E-12, vorticity computation on, integration
89 // step length 0.5 (unit cell length), maximum number of steps 2000,
90 // using 2nd order Runge Kutta and maximum propagation 1.0 (unit length).
91 static vtkStreamTracer *New();
94 // Specify the start of the streamline in the global coordinate
95 // system. Search must be performed to find initial cell to start
97 vtkSetVector3Macro(StartPosition, float);
98 vtkGetVector3Macro(StartPosition, float);
101 // Specify the source object used to generate starting points.
102 void SetSource(vtkDataSet *source);
103 vtkDataSet *GetSource();
122 enum ReasonForTermination
124 OUT_OF_DOMAIN = vtkInitialValueProblemSolver::OUT_OF_DOMAIN,
125 NOT_INITIALIZED = vtkInitialValueProblemSolver::NOT_INITIALIZED ,
126 UNEXPECTED_VALUE = vtkInitialValueProblemSolver::UNEXPECTED_VALUE,
134 // Set/get the integrator type to be used in the stream line
135 // calculation. The object passed is not actually used but
136 // is cloned with NewInstance in the process of integration
137 // (prototype pattern). The default is 2nd order Runge Kutta.
138 // The integrator can also be changed using SetIntegratorType.
139 // The recognized solvers are:
143 void SetIntegrator(vtkInitialValueProblemSolver *);
144 vtkGetObjectMacro ( Integrator, vtkInitialValueProblemSolver );
145 void SetIntegratorType(int type);
146 int GetIntegratorType();
147 void SetIntegratorTypeToRungeKutta2()
148 {this->SetIntegratorType(RUNGE_KUTTA2);};
149 void SetIntegratorTypeToRungeKutta4()
150 {this->SetIntegratorType(RUNGE_KUTTA4);};
151 void SetIntegratorTypeToRungeKutta45()
152 {this->SetIntegratorType(RUNGE_KUTTA45);};
155 // Specify the maximum length of the streamlines expressed in
159 // CELL_LENGTH_UNIT = 2
160 void SetMaximumPropagation(int unit, float max);
161 void SetMaximumPropagation(float max);
162 void SetMaximumPropagationUnit(int unit);
163 int GetMaximumPropagationUnit();
164 float GetMaximumPropagation();
165 void SetMaximumPropagationUnitToTimeUnit()
166 {this->SetMaximumPropagationUnit(TIME_UNIT);};
167 void SetMaximumPropagationUnitToLengthUnit()
168 {this->SetMaximumPropagationUnit(LENGTH_UNIT);};
169 void SetMaximumPropagationUnitToCellLengthUnit()
170 {this->SetMaximumPropagationUnit(CELL_LENGTH_UNIT);};
173 // Specify the minimum step used in the integration expressed in
177 // CELL_LENGTH_UNIT = 2
178 // Only valid when using adaptive integrators.
179 void SetMinimumIntegrationStep(int unit, float step);
180 void SetMinimumIntegrationStepUnit(int unit);
181 void SetMinimumIntegrationStep(float step);
182 int GetMinimumIntegrationStepUnit();
183 float GetMinimumIntegrationStep();
184 void SetMinimumIntegrationStepUnitToTimeUnit()
185 {this->SetMinimumIntegrationStepUnit(TIME_UNIT);};
186 void SetMinimumIntegrationStepUnitToLengthUnit()
187 {this->SetMinimumIntegrationStepUnit(LENGTH_UNIT);};
188 void SetMinimumIntegrationStepUnitToCellLengthUnit()
189 {this->SetMinimumIntegrationStepUnit(CELL_LENGTH_UNIT);};
192 // Specify the maximum step used in the integration expressed in
196 // CELL_LENGTH_UNIT = 2
197 // Only valid when using adaptive integrators.
198 void SetMaximumIntegrationStep(int unit, float step);
199 void SetMaximumIntegrationStepUnit(int unit);
200 void SetMaximumIntegrationStep(float step);
201 int GetMaximumIntegrationStepUnit();
202 float GetMaximumIntegrationStep();
203 void SetMaximumIntegrationStepUnitToTimeUnit()
204 {this->SetMaximumIntegrationStepUnit(TIME_UNIT);};
205 void SetMaximumIntegrationStepUnitToLengthUnit()
206 {this->SetMaximumIntegrationStepUnit(LENGTH_UNIT);};
207 void SetMaximumIntegrationStepUnitToCellLengthUnit()
208 {this->SetMaximumIntegrationStepUnit(CELL_LENGTH_UNIT);};
211 // Specify the initial step used in the integration expressed in
215 // CELL_LENGTH_UNIT = 2
216 // If the integrator is not adaptive, this is the actual
218 void SetInitialIntegrationStep(int unit, float step);
219 void SetInitialIntegrationStepUnit(int unit);
220 void SetInitialIntegrationStep(float step);
221 int GetInitialIntegrationStepUnit();
222 float GetInitialIntegrationStep();
223 void SetInitialIntegrationStepUnitToTimeUnit()
224 {this->SetInitialIntegrationStepUnit(TIME_UNIT);};
225 void SetInitialIntegrationStepUnitToLengthUnit()
226 {this->SetInitialIntegrationStepUnit(LENGTH_UNIT);};
227 void SetInitialIntegrationStepUnitToCellLengthUnit()
228 {this->SetInitialIntegrationStepUnit(CELL_LENGTH_UNIT);};
231 // Specify the maximum error in the integration. This value
232 // is passed to the integrator. Therefore, it's meaning depends
233 // on the integrator used.
234 vtkSetMacro(MaximumError, float);
235 vtkGetMacro(MaximumError, float);
238 // Specify the maximum number of steps used in the integration.
239 vtkSetMacro(MaximumNumberOfSteps, vtkIdType);
240 vtkGetMacro(MaximumNumberOfSteps, vtkIdType);
243 // If at any point, the speed is below this value, the integration
245 vtkSetMacro(TerminalSpeed, float);
246 vtkGetMacro(TerminalSpeed, float);
258 // Specify whether the streamtrace will be generated in the
259 // upstream or downstream direction.
260 vtkSetClampMacro(IntegrationDirection, int, FORWARD, BOTH);
261 vtkGetMacro(IntegrationDirection, int);
262 void SetIntegrationDirectionToForward()
263 {this->SetIntegrationDirection(FORWARD);};
264 void SetIntegrationDirectionToBackward()
265 {this->SetIntegrationDirection(BACKWARD);};
266 void SetIntegrationDirectionToBoth()
267 {this->SetIntegrationDirection(BOTH);};
270 // Turn on/off calculation of vorticity at streamline points
271 // (necessary for generating proper streamribbons using the
273 vtkSetMacro(ComputeVorticity, int);
274 vtkGetMacro(ComputeVorticity, int);
275 vtkBooleanMacro(ComputeVorticity, int);
278 // This can be used to scale the rate with which the streamribbons
279 // twist. The default is 1.
280 vtkSetMacro(RotationScale, float);
281 vtkGetMacro(RotationScale, float);
284 // Add a dataset to the list inputs
285 void AddInput(vtkDataSet *in);
292 // hide the superclass' AddInput() from the user and the compiler
293 void AddInput(vtkDataObject *)
294 { vtkErrorMacro( << "AddInput() must be called with a vtkDataSet not a vtkDataObject."); };
297 void CalculateVorticity( vtkGenericCell* cell, float pcoords[3],
298 vtkFloatArray* cellVectors, float vorticity[3] );
299 void Integrate(vtkPolyData* output,
300 vtkDataArray* seedSource,
302 vtkIntArray* integrationDirections,
304 int CheckInputs(vtkInterpolatedVelocityField*& func,
307 vtkSetStringMacro(InputVectorsSelection);
308 char *InputVectorsSelection;
311 // starting from global x-y-z position
312 float StartPosition[3];
314 static const float EPSILON;
318 struct IntervalInformation
324 IntervalInformation MaximumPropagation;
325 IntervalInformation MinimumIntegrationStep;
326 IntervalInformation MaximumIntegrationStep;
327 IntervalInformation InitialIntegrationStep;
329 void SetIntervalInformation(int unit, float interval,
330 IntervalInformation& currentValues);
331 void SetIntervalInformation(int unit,IntervalInformation& currentValues);
332 static float ConvertToTime(IntervalInformation& interval,
333 float cellLength, float speed);
334 static float ConvertToLength(IntervalInformation& interval,
335 float cellLength, float speed);
336 static float ConvertToCellLength(IntervalInformation& interval,
337 float cellLength, float speed);
338 static float ConvertToUnit(IntervalInformation& interval, int unit,
339 float cellLength, float speed);
340 void ConvertIntervals(float& step, float& minStep, float& maxStep,
341 int direction, float cellLength, float speed);
344 void InitializeSeeds(vtkDataArray*& seeds,
346 vtkIntArray*& integrationDirections);
348 int IntegrationDirection;
350 // Prototype showing the integrator type to be set by the user.
351 vtkInitialValueProblemSolver* Integrator;
354 vtkIdType MaximumNumberOfSteps;
356 int ComputeVorticity;
360 vtkStreamTracer(const vtkStreamTracer&); // Not implemented.
361 void operator=(const vtkStreamTracer&); // Not implemented.