You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
386 lines
12 KiB
C
386 lines
12 KiB
C
|
3 weeks ago
|
/*=========================================================================
|
||
|
|
|
||
|
|
Program: Visualization Toolkit
|
||
|
|
Module: vtkStreamer.h
|
||
|
|
|
||
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
|
All rights reserved.
|
||
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
|
||
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
|
||
|
|
=========================================================================*/
|
||
|
|
/**
|
||
|
|
* @class vtkStreamer
|
||
|
|
* @brief abstract object implements integration of massless particle through vector field
|
||
|
|
*
|
||
|
|
* vtkStreamer is a filter that integrates a massless particle through a vector
|
||
|
|
* field. The integration is performed using second order Runge-Kutta method.
|
||
|
|
* vtkStreamer often serves as a base class for other classes that perform
|
||
|
|
* numerical integration through a vector field (e.g., vtkStreamLine).
|
||
|
|
*
|
||
|
|
* Note that vtkStreamer can integrate both forward and backward in time,
|
||
|
|
* or in both directions. The length of the streamer is controlled by
|
||
|
|
* specifying an elapsed time. (The elapsed time is the time each particle
|
||
|
|
* travels.) Otherwise, the integration terminates after exiting the dataset or
|
||
|
|
* if the particle speed is reduced to a value less than the terminal speed.
|
||
|
|
*
|
||
|
|
* vtkStreamer integrates through any type of dataset. As a result, if the
|
||
|
|
* dataset contains 2D cells such as polygons or triangles, the integration is
|
||
|
|
* constrained to lie on the surface defined by the 2D cells.
|
||
|
|
*
|
||
|
|
* The starting point of streamers may be defined in three different ways.
|
||
|
|
* Starting from global x-y-z "position" allows you to start a single streamer
|
||
|
|
* at a specified x-y-z coordinate. Starting from "location" allows you to
|
||
|
|
* start at a specified cell, subId, and parametric coordinate. Finally, you
|
||
|
|
* may specify a source object to start multiple streamers. If you start
|
||
|
|
* streamers using a source object, for each point in the source that is
|
||
|
|
* inside the dataset a streamer is created.
|
||
|
|
*
|
||
|
|
* vtkStreamer implements the integration process in the Integrate() method.
|
||
|
|
* Because vtkStreamer does not implement the Execute() method that its
|
||
|
|
* superclass (i.e., Filter) requires, it is an abstract class. Its subclasses
|
||
|
|
* implement the execute method and use the Integrate() method, and then build
|
||
|
|
* their own representation of the integration path (i.e., lines, dashed
|
||
|
|
* lines, points, etc.).
|
||
|
|
*
|
||
|
|
* @sa
|
||
|
|
* vtkStreamLine vtkDashedStreamLine vtkStreamPoints
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef vtkStreamer_h
|
||
|
|
#define vtkStreamer_h
|
||
|
|
|
||
|
|
#include "vtkFiltersFlowPathsModule.h" // For export macro
|
||
|
|
#include "vtkPolyDataAlgorithm.h"
|
||
|
|
|
||
|
|
class vtkInitialValueProblemSolver;
|
||
|
|
class vtkMultiThreader;
|
||
|
|
|
||
|
|
#ifndef VTK_LEGACY_REMOVE
|
||
|
|
|
||
|
|
#define VTK_INTEGRATE_FORWARD 0
|
||
|
|
#define VTK_INTEGRATE_BACKWARD 1
|
||
|
|
#define VTK_INTEGRATE_BOTH_DIRECTIONS 2
|
||
|
|
|
||
|
|
class VTKFILTERSFLOWPATHS_EXPORT vtkStreamer : public vtkPolyDataAlgorithm
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
vtkTypeMacro(vtkStreamer,vtkPolyDataAlgorithm);
|
||
|
|
void PrintSelf(ostream& os, vtkIndent indent);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specify the start of the streamline in the cell coordinate system. That
|
||
|
|
* is, cellId and subId (if composite cell), and parametric coordinates.
|
||
|
|
*/
|
||
|
|
void SetStartLocation(vtkIdType cellId, int subId, double pcoords[3]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specify the start of the streamline in the cell coordinate system. That
|
||
|
|
* is, cellId and subId (if composite cell), and parametric coordinates.
|
||
|
|
*/
|
||
|
|
void SetStartLocation(vtkIdType cellId, int subId, double r, double s,
|
||
|
|
double t);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the starting location of the streamline in the cell coordinate system.
|
||
|
|
*/
|
||
|
|
vtkIdType GetStartLocation(int& subId, double pcoords[3]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specify the start of the streamline in the global coordinate
|
||
|
|
* system. Search must be performed to find initial cell to start
|
||
|
|
* integration from.
|
||
|
|
*/
|
||
|
|
void SetStartPosition(double x[3]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specify the start of the streamline in the global coordinate
|
||
|
|
* system. Search must be performed to find initial cell to start
|
||
|
|
* integration from.
|
||
|
|
*/
|
||
|
|
void SetStartPosition(double x, double y, double z);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the start position in global x-y-z coordinates.
|
||
|
|
*/
|
||
|
|
double *GetStartPosition();
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Specify the source object used to generate starting points.
|
||
|
|
*/
|
||
|
|
void SetSourceData(vtkDataSet *source);
|
||
|
|
vtkDataSet *GetSource();
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specify the source object used to generate starting points
|
||
|
|
* by making a pipeline connection
|
||
|
|
*/
|
||
|
|
void SetSourceConnection(vtkAlgorithmOutput* algOutput);
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Specify the maximum length of the Streamer expressed in elapsed time.
|
||
|
|
*/
|
||
|
|
vtkSetClampMacro(MaximumPropagationTime,double,0.0,VTK_DOUBLE_MAX);
|
||
|
|
vtkGetMacro(MaximumPropagationTime,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Specify the direction in which to integrate the Streamer.
|
||
|
|
*/
|
||
|
|
vtkSetClampMacro(IntegrationDirection,int,
|
||
|
|
VTK_INTEGRATE_FORWARD,VTK_INTEGRATE_BOTH_DIRECTIONS);
|
||
|
|
vtkGetMacro(IntegrationDirection,int);
|
||
|
|
void SetIntegrationDirectionToForward()
|
||
|
|
{this->SetIntegrationDirection(VTK_INTEGRATE_FORWARD);};
|
||
|
|
void SetIntegrationDirectionToBackward()
|
||
|
|
{this->SetIntegrationDirection(VTK_INTEGRATE_BACKWARD);};
|
||
|
|
void SetIntegrationDirectionToIntegrateBothDirections()
|
||
|
|
{this->SetIntegrationDirection(VTK_INTEGRATE_BOTH_DIRECTIONS);};
|
||
|
|
const char *GetIntegrationDirectionAsString();
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Specify a nominal integration step size (expressed as a fraction of
|
||
|
|
* the size of each cell). This value can be larger than 1.
|
||
|
|
*/
|
||
|
|
vtkSetClampMacro(IntegrationStepLength,double,0.0000001,VTK_DOUBLE_MAX);
|
||
|
|
vtkGetMacro(IntegrationStepLength,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Turn on/off the creation of scalar data from velocity magnitude. If off,
|
||
|
|
* and input dataset has scalars, input dataset scalars are used.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(SpeedScalars,int);
|
||
|
|
vtkGetMacro(SpeedScalars,int);
|
||
|
|
vtkBooleanMacro(SpeedScalars,int);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Turn on/off the creation of scalar data from vorticity information.
|
||
|
|
* The scalar information is currently the orientation value "theta"
|
||
|
|
* used in rotating stream tubes. If off, and input dataset has scalars,
|
||
|
|
* then input dataset scalars are used, unless SpeedScalars is also on.
|
||
|
|
* SpeedScalars takes precedence over OrientationScalars.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(OrientationScalars, int);
|
||
|
|
vtkGetMacro(OrientationScalars, int);
|
||
|
|
vtkBooleanMacro(OrientationScalars, int);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Set/get terminal speed (i.e., speed is velocity magnitude). Terminal
|
||
|
|
* speed is speed at which streamer will terminate propagation.
|
||
|
|
*/
|
||
|
|
vtkSetClampMacro(TerminalSpeed,double,0.0,VTK_DOUBLE_MAX);
|
||
|
|
vtkGetMacro(TerminalSpeed,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Turn on/off the computation of vorticity. Vorticity is an indication of
|
||
|
|
* the rotation of the flow. In combination with vtkStreamLine and
|
||
|
|
* vtkTubeFilter can be used to create rotated tubes.
|
||
|
|
* If vorticity is turned on, in the output, the velocity vectors
|
||
|
|
* are replaced by vorticity vectors.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(Vorticity,int);
|
||
|
|
vtkGetMacro(Vorticity,int);
|
||
|
|
vtkBooleanMacro(Vorticity,int);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
vtkSetMacro( NumberOfThreads, int );
|
||
|
|
vtkGetMacro( NumberOfThreads, int );
|
||
|
|
|
||
|
|
vtkSetMacro( SavePointInterval, double );
|
||
|
|
vtkGetMacro( SavePointInterval, double );
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Set/get the integrator type to be used in the stream line
|
||
|
|
* calculation. The object passed is not actually used but
|
||
|
|
* is cloned with NewInstance by each thread/process in the
|
||
|
|
* process of integration (prototype pattern). The default is
|
||
|
|
* 2nd order Runge Kutta.
|
||
|
|
*/
|
||
|
|
void SetIntegrator(vtkInitialValueProblemSolver *);
|
||
|
|
vtkGetObjectMacro ( Integrator, vtkInitialValueProblemSolver );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* A positive value, as small as possible for numerical comparison.
|
||
|
|
* The initial value is 1E-12.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(Epsilon,double);
|
||
|
|
vtkGetMacro(Epsilon,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
protected:
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Construct object to start from position (0,0,0); integrate forward;
|
||
|
|
* terminal speed 0.0; vorticity computation off; integrations step length
|
||
|
|
* 0.2; and maximum propagation time 100.0.
|
||
|
|
*/
|
||
|
|
vtkStreamer();
|
||
|
|
~vtkStreamer();
|
||
|
|
//@}
|
||
|
|
|
||
|
|
// Integrate data
|
||
|
|
void Integrate(vtkDataSet *input, vtkDataSet *source);
|
||
|
|
|
||
|
|
// Controls where streamlines start from (either position or location).
|
||
|
|
int StartFrom;
|
||
|
|
|
||
|
|
// Starting from cell location
|
||
|
|
vtkIdType StartCell;
|
||
|
|
int StartSubId;
|
||
|
|
double StartPCoords[3];
|
||
|
|
|
||
|
|
// starting from global x-y-z position
|
||
|
|
double StartPosition[3];
|
||
|
|
|
||
|
|
//
|
||
|
|
// Special classes for manipulating data
|
||
|
|
//
|
||
|
|
class StreamPoint {
|
||
|
|
public:
|
||
|
|
double x[3]; // position
|
||
|
|
vtkIdType cellId; // cell
|
||
|
|
int subId; // cell sub id
|
||
|
|
double p[3]; // parametric coords in cell
|
||
|
|
double v[3]; // velocity
|
||
|
|
double speed; // velocity norm
|
||
|
|
double s; // scalar value
|
||
|
|
double t; // time travelled so far
|
||
|
|
double d; // distance travelled so far
|
||
|
|
double omega; // stream vorticity, if computed
|
||
|
|
double theta; // rotation angle, if vorticity is computed
|
||
|
|
};
|
||
|
|
|
||
|
|
class StreamArray;
|
||
|
|
friend class StreamArray;
|
||
|
|
class StreamArray { //;prevent man page generation
|
||
|
|
public:
|
||
|
|
StreamArray();
|
||
|
|
~StreamArray()
|
||
|
|
{
|
||
|
|
delete [] this->Array;
|
||
|
|
};
|
||
|
|
vtkIdType GetNumberOfPoints() {return this->MaxId + 1;};
|
||
|
|
StreamPoint *GetStreamPoint(vtkIdType i) {return this->Array + i;};
|
||
|
|
vtkIdType InsertNextStreamPoint()
|
||
|
|
{
|
||
|
|
if ( ++this->MaxId >= this->Size )
|
||
|
|
{
|
||
|
|
this->Resize(this->MaxId);
|
||
|
|
}
|
||
|
|
return this->MaxId; //return offset from array
|
||
|
|
}
|
||
|
|
StreamPoint *Resize(vtkIdType sz); //reallocates data
|
||
|
|
void Reset() {this->MaxId = -1;};
|
||
|
|
|
||
|
|
StreamPoint *Array; // pointer to data
|
||
|
|
vtkIdType MaxId; // maximum index inserted thus far
|
||
|
|
vtkIdType Size; // allocated size of data
|
||
|
|
vtkIdType Extend; // grow array by this amount
|
||
|
|
double Direction; // integration direction
|
||
|
|
};
|
||
|
|
|
||
|
|
//
|
||
|
|
|
||
|
|
//array of streamers
|
||
|
|
StreamArray *Streamers;
|
||
|
|
vtkIdType NumberOfStreamers;
|
||
|
|
|
||
|
|
// length of Streamer is generated by time, or by MaximumSteps
|
||
|
|
double MaximumPropagationTime;
|
||
|
|
|
||
|
|
// integration direction
|
||
|
|
int IntegrationDirection;
|
||
|
|
|
||
|
|
// the length (fraction of cell size) of integration steps
|
||
|
|
double IntegrationStepLength;
|
||
|
|
|
||
|
|
// boolean controls whether vorticity is computed
|
||
|
|
int Vorticity;
|
||
|
|
|
||
|
|
// terminal propagation speed
|
||
|
|
double TerminalSpeed;
|
||
|
|
|
||
|
|
// boolean controls whether data scalars or velocity magnitude are used
|
||
|
|
int SpeedScalars;
|
||
|
|
|
||
|
|
// boolean controls whether data scalars or vorticity orientation are used
|
||
|
|
int OrientationScalars;
|
||
|
|
|
||
|
|
// Prototype showing the integrator type to be set by the user.
|
||
|
|
vtkInitialValueProblemSolver* Integrator;
|
||
|
|
|
||
|
|
// A positive value, as small as possible for numerical comparison.
|
||
|
|
// The initial value is 1E-12.
|
||
|
|
double Epsilon;
|
||
|
|
|
||
|
|
// Interval with which the stream points will be stored.
|
||
|
|
// Useful in reducing the memory footprint. Since the initial
|
||
|
|
// value is small, by default, it will store all/most points.
|
||
|
|
double SavePointInterval;
|
||
|
|
|
||
|
|
static VTK_THREAD_RETURN_TYPE ThreadedIntegrate( void *arg );
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* These methods were added to allow access to these variables from the
|
||
|
|
* threads.
|
||
|
|
*/
|
||
|
|
vtkGetMacro( NumberOfStreamers, vtkIdType );
|
||
|
|
StreamArray *GetStreamers() { return this->Streamers; };
|
||
|
|
//@}
|
||
|
|
|
||
|
|
void InitializeThreadedIntegrate();
|
||
|
|
vtkMultiThreader *Threader;
|
||
|
|
int NumberOfThreads;
|
||
|
|
|
||
|
|
virtual int FillInputPortInformation(int port, vtkInformation *info);
|
||
|
|
|
||
|
|
private:
|
||
|
|
vtkStreamer(const vtkStreamer&) VTK_DELETE_FUNCTION;
|
||
|
|
void operator=(const vtkStreamer&) VTK_DELETE_FUNCTION;
|
||
|
|
};
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Return the integration direction as a character string.
|
||
|
|
*/
|
||
|
|
inline const char *vtkStreamer::GetIntegrationDirectionAsString()
|
||
|
|
{
|
||
|
|
if ( this->IntegrationDirection == VTK_INTEGRATE_FORWARD )
|
||
|
|
{
|
||
|
|
return "IntegrateForward";
|
||
|
|
}
|
||
|
|
else if ( this->IntegrationDirection == VTK_INTEGRATE_BACKWARD )
|
||
|
|
{
|
||
|
|
return "IntegrateBackward";
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return "IntegrateBothDirections";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//@}
|
||
|
|
|
||
|
|
#endif // VTK_LEGACY_REMOVE
|
||
|
|
#endif
|